From 0a18e8f4e60f7187f95e0f927ae0e03ffdb6208e Mon Sep 17 00:00:00 2001 From: Jean-Francois Dockes Date: Sat, 13 Apr 2019 09:24:14 +0200 Subject: [PATCH] doc --- src/doc/user/Makefile | 6 +- src/doc/user/sphinx/Makefile | 225 - .../sphinx/_build/doctrees/environment.pickle | Bin 45417 -> 0 bytes .../_build/doctrees/source/usermanual.doctree | Bin 1043010 -> 0 bytes .../sphinx/_build/doctrees/usermanual.doctree | Bin 1030673 -> 0 bytes src/doc/user/sphinx/_build/html/.buildinfo | 4 - .../html/_sources/source/usermanual.txt | 6006 --------- .../_build/html/_sources/usermanual.txt | 5985 --------- .../_build/html/_static/ajax-loader.gif | Bin 673 -> 0 bytes .../sphinx/_build/html/_static/alabaster.css | 607 - .../user/sphinx/_build/html/_static/basic.css | 611 - .../_build/html/_static/comment-bright.png | Bin 3500 -> 0 bytes .../_build/html/_static/comment-close.png | Bin 3578 -> 0 bytes .../sphinx/_build/html/_static/comment.png | Bin 3445 -> 0 bytes .../sphinx/_build/html/_static/custom.css | 1 - .../sphinx/_build/html/_static/doctools.js | 287 - .../_build/html/_static/down-pressed.png | Bin 347 -> 0 bytes .../user/sphinx/_build/html/_static/down.png | Bin 347 -> 0 bytes .../user/sphinx/_build/html/_static/file.png | Bin 358 -> 0 bytes .../user/sphinx/_build/html/_static/jquery.js | 10219 ---------------- .../user/sphinx/_build/html/_static/minus.png | Bin 173 -> 0 bytes .../user/sphinx/_build/html/_static/plus.png | Bin 173 -> 0 bytes .../sphinx/_build/html/_static/pygments.css | 69 - .../sphinx/_build/html/_static/searchtools.js | 751 -- .../sphinx/_build/html/_static/underscore.js | 1548 --- .../sphinx/_build/html/_static/up-pressed.png | Bin 345 -> 0 bytes .../user/sphinx/_build/html/_static/up.png | Bin 345 -> 0 bytes .../sphinx/_build/html/_static/websupport.js | 808 -- src/doc/user/sphinx/_build/html/genindex.html | 93 - src/doc/user/sphinx/_build/html/objects.inv | Bin 236 -> 0 bytes src/doc/user/sphinx/_build/html/search.html | 103 - .../user/sphinx/_build/html/searchindex.js | 1 - .../sphinx/_build/html/source/usermanual.html | 5435 -------- .../user/sphinx/_build/html/usermanual.html | 5364 -------- src/doc/user/sphinx/conf.py | 339 - .../user/sphinx/{usermanual.rst => index.rst} | 14 +- src/doc/user/usermanual.html | 33 +- src/doc/user/usermanual.xml | 338 +- 38 files changed, 185 insertions(+), 38662 deletions(-) delete mode 100644 src/doc/user/sphinx/Makefile delete mode 100644 src/doc/user/sphinx/_build/doctrees/environment.pickle delete mode 100644 src/doc/user/sphinx/_build/doctrees/source/usermanual.doctree delete mode 100644 src/doc/user/sphinx/_build/doctrees/usermanual.doctree delete mode 100644 src/doc/user/sphinx/_build/html/.buildinfo delete mode 100644 src/doc/user/sphinx/_build/html/_sources/source/usermanual.txt delete mode 100644 src/doc/user/sphinx/_build/html/_sources/usermanual.txt delete mode 100644 src/doc/user/sphinx/_build/html/_static/ajax-loader.gif delete mode 100644 src/doc/user/sphinx/_build/html/_static/alabaster.css delete mode 100644 src/doc/user/sphinx/_build/html/_static/basic.css delete mode 100644 src/doc/user/sphinx/_build/html/_static/comment-bright.png delete mode 100644 src/doc/user/sphinx/_build/html/_static/comment-close.png delete mode 100644 src/doc/user/sphinx/_build/html/_static/comment.png delete mode 100644 src/doc/user/sphinx/_build/html/_static/custom.css delete mode 100644 src/doc/user/sphinx/_build/html/_static/doctools.js delete mode 100644 src/doc/user/sphinx/_build/html/_static/down-pressed.png delete mode 100644 src/doc/user/sphinx/_build/html/_static/down.png delete mode 100644 src/doc/user/sphinx/_build/html/_static/file.png delete mode 100644 src/doc/user/sphinx/_build/html/_static/jquery.js delete mode 100644 src/doc/user/sphinx/_build/html/_static/minus.png delete mode 100644 src/doc/user/sphinx/_build/html/_static/plus.png delete mode 100644 src/doc/user/sphinx/_build/html/_static/pygments.css delete mode 100644 src/doc/user/sphinx/_build/html/_static/searchtools.js delete mode 100644 src/doc/user/sphinx/_build/html/_static/underscore.js delete mode 100644 src/doc/user/sphinx/_build/html/_static/up-pressed.png delete mode 100644 src/doc/user/sphinx/_build/html/_static/up.png delete mode 100644 src/doc/user/sphinx/_build/html/_static/websupport.js delete mode 100644 src/doc/user/sphinx/_build/html/genindex.html delete mode 100644 src/doc/user/sphinx/_build/html/objects.inv delete mode 100644 src/doc/user/sphinx/_build/html/search.html delete mode 100644 src/doc/user/sphinx/_build/html/searchindex.js delete mode 100644 src/doc/user/sphinx/_build/html/source/usermanual.html delete mode 100644 src/doc/user/sphinx/_build/html/usermanual.html delete mode 100644 src/doc/user/sphinx/conf.py rename src/doc/user/sphinx/{usermanual.rst => index.rst} (99%) diff --git a/src/doc/user/Makefile b/src/doc/user/Makefile index b6a94b06..33eae7ef 100644 --- a/src/doc/user/Makefile +++ b/src/doc/user/Makefile @@ -60,8 +60,10 @@ usermanual-rst: recoll-conf-xml < usermanual.xml > full-man.xml sed -i -e '/xi:include/d' -e '//d' full-man.xml test -d sphinx || mkdir sphinx - pandoc -s --toc -f docbook -t rst full-man.xml > sphinx/usermanual.rst - (cd sphinx;make html) + pandoc -s --toc -f docbook -t rst full-man.xml > sphinx/index.rst + -@echo fix termmatch and execute + +#(cd sphinx;make html) clean: rm -f RCL.*.html usermanual.pdf usermanual.html index.html tmpfile.html diff --git a/src/doc/user/sphinx/Makefile b/src/doc/user/sphinx/Makefile deleted file mode 100644 index f64d70fc..00000000 --- a/src/doc/user/sphinx/Makefile +++ /dev/null @@ -1,225 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " applehelp to make an Apple Help Book" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " epub3 to make an epub3" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - @echo " coverage to run coverage check of the documentation (if enabled)" - @echo " dummy to check syntax errors of document sources" - -.PHONY: clean -clean: - rm -rf $(BUILDDIR)/* - -.PHONY: html -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -.PHONY: dirhtml -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -.PHONY: singlehtml -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -.PHONY: pickle -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -.PHONY: json -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -.PHONY: htmlhelp -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -.PHONY: qthelp -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/recoll.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/recoll.qhc" - -.PHONY: applehelp -applehelp: - $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp - @echo - @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." - @echo "N.B. You won't be able to view it unless you put it in" \ - "~/Library/Documentation/Help or install it in your application" \ - "bundle." - -.PHONY: devhelp -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/recoll" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/recoll" - @echo "# devhelp" - -.PHONY: epub -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -.PHONY: epub3 -epub3: - $(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3 - @echo - @echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3." - -.PHONY: latex -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -.PHONY: latexpdf -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -.PHONY: latexpdfja -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -.PHONY: text -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -.PHONY: man -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -.PHONY: texinfo -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -.PHONY: info -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -.PHONY: gettext -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -.PHONY: changes -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -.PHONY: linkcheck -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -.PHONY: doctest -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -.PHONY: coverage -coverage: - $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage - @echo "Testing of coverage in the sources finished, look at the " \ - "results in $(BUILDDIR)/coverage/python.txt." - -.PHONY: xml -xml: - $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -.PHONY: pseudoxml -pseudoxml: - $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." - -.PHONY: dummy -dummy: - $(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy - @echo - @echo "Build finished. Dummy builder generates no files." diff --git a/src/doc/user/sphinx/_build/doctrees/environment.pickle b/src/doc/user/sphinx/_build/doctrees/environment.pickle deleted file mode 100644 index fd545a7769a0c639c05839d3ee02dfeb9ef00cb5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45417 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

=w1U z57rcR7)nF@q~0v##kYP|G*cG!_1ISu_4=ZAIW8eEEv(cMAuNT|trZ6Ag$7Mj)(0%3 z7qVHVXMSZB2_-kS2qJUn!$J)zHZyaPJwfr8QF|WkKtv!0*h82=HRvB(Ht5KW`N~2E_Geo$F&Ja6e<6fnw^f=b#%%jM z4@x-~7LRc~I^f13qwu~ofPz6Z>2neJz^`Lw$k#^*7gZjUAPYVBo>1y|lv$IB3 zT8!rI>qMOhlH5*sl@O;4!in;?=4+ukcSm#Rn~ax~BFZDBGIU%vU742{$lL-c1NAf2 zNcp3=7W&$Q)HQ1zv}#5t8uYA(i%=<96RA{;SUz4!P`{PksL?5TSRLxC0|*ropq6be zA2M~s44L{i&pD4wU6Yy3yQd4U#P6NG;9Gi0uei+myaeMj4 z{1qz-oh1uSWtE%cuBtcVAB`Qo+CAwl4aTXNrpPMRbVO)Y>;FMK1qodMqFZ>DG=zGx z3@%Ygf<5`$sb(!L;B137CDtD(!Yb5gA64vVGbh?5ngG5N6_mX~1!NtKQ=tVsOa6ey zbczwmDc57T4m#{b9w5V06eO)VLS?NS)tV4)AmP+vNFp%jNeN&$9*C%LXdJIZizwgQ zC_xIr&w>9KjU`JagM+9_QYm(7Vaw@eI+Xb9oezE-L9azfDWDn6H2Hz9cGVlzZn(Xc z#5f5M2pj|jA$U+=j-*FieDqn@%CN-Z>w}4foy}cYJ{0SS8Dg=80F+BCGP8Na;%Nea zR-&15(DyibT0M=Jc|IU?1dR~_OHKT?`6?RHO! zSA(f~_ocJ5nnbmdH`ipKL%-A_6wYSV4Cx5AIw8mzls<;$ld2Y?#_>ukZjg>slRUI* z$AP_jj~v~-XYcf`Lr0G8+di{z*S_0#9eVcAKGbgvAaW>@-n)r>P}Siw6t2R<%%gBu z`crx2?LN5)OWqdTHQXytt0!;WX2y4N+HWTR6#uV5_-^C$t<3;U56pPS{t7wvGjKR6 zM7=0;&ndd`>CKneY|od=Q~BzRFFE$+5B>w+V_nz#OA6*X0kJr6X7(HR|Pp1eJzSD7}AQC%Br9% zDOHP6p%jDLL?jB(I}^r{O3Vu+>V6}b7@B6(g4B-CQt>#5ek;p!#z2U;3sFlAbrNJ# z4_nZ6Vai)XN>-@>rw7u1QGE*mI24(aLR>6%P^)Vivb9ODQeBz}X3X)otG=75!5s;< z>CHFB7}O--bdlY#xCt}}ha1RF?&&OJd@4n8pU4ku$mYe-Hn2|ZyQ*DEDs_nFI2)KH zb&rs@qc(-?l}WzB{dWiO9%$psE_B!tGwkON35qMPMQit5lbOvUg?}cXY&pK4KR5mXhShw)`i|kqqq}0*PEQ?!2l}p39`i*( z%<7jMM*fX^Qrx7h@LP(d{rJYWFJ{|rgZSVMJLBRsObGos2aOuehJuDgG{~4x5YWAp z#iN`eI1NaoP&6It~L`kE0z$G+{40?z{i6iO;m<1!PbhtOq~|p;k2RJ zAreha?li(;F>0dG7pyV~OJHO|K*@Z>cjZq*`xK^8`^`ce!z8QRFKiUWcqIoB*HHgL zd}(A`J7D%jmV<`R;BU*($Y-`pZUx6}(-7sNWeTP+t$PtCzGd=>B4rtCS5Rujh7aPa zCo88Ere6XNSKF7~8s@`AG?E&uU+{Xh;yMdaAU>y}9N6p!9R9B9-4joR85*WF#L}L? zitRca*TpF!FFR^YP#PHbgo$ycO*GMlz1`8S3JI!%Aj-`^hh%FvXxWB)KZPE(_@V6P zmdz7eH$RSvFxo~<1&NTRE(1_`lpqx;<{5Z| z^)LZOpzy```WWXK{kWS*X|F5930Gla(qQFHt zQHJmb-!dND0Ypihyw_(a`*Wm62ZoMZVnIa7fRnVJZggWjoA#D?= zcm8~yn0nDws!XW@{T;^&zpe~$^NbH`0_wn$k#9>Zfd+51NvvVmv}rjOzE{AJsC} zxhK^!atv;NC61a#+~|nY+Zoza85O^owdPoNni?j|4^**-ApkCiC|JK`>#gg@3+tg7 zM^9cq9&CBq*2yhTe(I!X{EKl17AK>ri=qtW78;_P+=NdR#@34)gJZ#B!XK&aX)Zz` zjs3b%skIkF4R0Wd2~mfzi$TjpZ9lPP#Hj8|{}APUt2k3}Ez4*Kw3-t(VXX$RJ0K?v zW;QXoNKdD*R)8%}?L-JOslbqw6e}jBCAB)LiLKmWIF>Y4mq18!Hni126|2*#hPBbY zAn_>y}19#D4IkqKh$K^ovV^h0iSVj6V0~G12 zSo_1lM7{u`V`UWRClWUE6zI#{JRVd(L!jFFceXl^9+RilM;Od})cJQtfPU@*dOln} z(hA0-3kT&m=P8>u@Ho5{P-wp^&C`BitDv+}fhn&184PNsI9lQ*1y9k&=lcTVpz^&|f`0fuVV zLBUJhlfpv|cE4$MmU(kR1_7)7usc@)V>f&E1kN;SOSOm zDcq27P9uULMkflF9t(W1nq;Yx6p`f0E?v_Ip|+t0c;kti#m!0IEKv+vPnr#@9!U7i z=>TUQExrv)Rm8|KvHu=;#-;R@b#1fa6*MMwL7KK0!a+s392N&R55U27%T6O7I&{1Y z{{2s0OCJ7R)pPP5?tMuv)#Bdg+>QRFJgoulz5iUj)EOG zMFN6h=xw==z}XW92vdk}NLg)V$P!Y)NFkbq+1!S#*_w=KhC+`5u^5rJSK8z34rOdL zI1L-VgB2oT2nAa~fnZ~2w+IGUXsiSGFtjZGlmTSra@t#rVyoLnq( zcx2@J_$!y;dL8~!gW_fKw0bf!^W!iLe`c|es92e%qJHag_*8FM{U*ea+{ zeWJsGjqXXYA%~D&BZL$v+*m-q2!tY#Q!(eds?{pDh&Un%#UOT#3BH_2h?{5}qF<06 zk>-(rX^@|lmNe8KKio>YxwC0Y9&xi(fl-50t&SRhk`{qD$L(6vpOp1hV^|jx16~3} zgkhnG1b)~jNYhZ>xk=_4#a6?J{m2R{0 z+JpV1QmL;hKv}IhXbjzx!sTFM)%}o(w`bWm7{?ZBNGIyBf(MA!Ui&NrNn^vImYM1w z_7`xTLG}~Up@Hv*ITSQMDblgjk0Nbg6_;c zV$+p-wZ!J7?ov<4(;5()x18;_n}7b#wB+FI-%E7>jPl?Y{hlH3^Xvkza4wz!f6&NK=U^WBLS*s*WbvN-gV~$Eg zGg_p-#5NH_w6F&q} zi!?WX?3TSdjvU>-ckg&0PdldXIk=0@+xOqGQ3wxHs1Q4a@+*kkk0+k`)F(Y{VoNYq zY))+1`XmThXb^&Q2kd(fYR}S}#!BqW7J-07wUVY`Nb}avYZq)!8YjgKVFnz$D6O1Y zge|jIopD@Jfp`WG*C5Buu^79^1%{9!UV!(4t%}3KwyMR0 z2Xpdae3xN3GnbCwhED7}it7mO(eszydgSVJLas(cWyFqCc6?IJsDG8=T{%MDXOPf_ zLeoh9J*uIJMUS^}6JiaU zr6Db_24${U4pA?+P=q}B0(jNSm8KfcH71jy5p+G{9+2{QQ~@W0T_MCJv~iOHOPH3j zofzCFl8BWuWR=WHy?rJo? z;hg8thfaoer@@sM(j;RW<|DzMp*M4S`o`KVG1*B0wlb94L*x7J z_K#j0N5LPx2LHMLmqYyL<@nFPzVpS{%fG(!CG!>h_oef-;Qn8_|CfUMe;ogr4DNt4 zIc)TuvXC=na0*lIX#~5GZ(jtwLiXm_X$Y_g?YM!GbZd&4gs)B=ESv|}i09%GP(=cV zrLcWymW&OrbWX#cgxs8SfQvj2Wa%Kr1gZAWFR0jHt!;#WQPGmB1@ap#)Gk>RG{BVc zYPmu;w6zeGo!=aw(P^+AHgKQm-fjljT|st7NJPzQlp#?40tRUyovlzanYZIY-rWxw z`Z7B}IYH=4AG(+?yXlx2{p8=tvGeqkb<5`Sc>ezro^Mr@|Le&7KgrV?s3;!>D;N>| z5z!wJee#(R(HH7`P7(cl+I+z3)$bb-JFwspv3nqhU5{ql&+hzCt zjEhH!#Ax1m4+{s3k5_GU#^2{#%1m-IIz_4KC(SQPvY^e!j-&n0OhkrK)rB1y`S2I1{VkPOc=TSqDQEbNlok&^VVI8N@ z0NVr{r`fIN3%@#G#xOBS9+GF6xVm>Tj|DwhSdg_!jJpe5FHfttN_5|TF5GDT*%yuC zagOXKjUw4A7hK)%Zgz)z(mNiEq%${2jA|`LHR<_ER4Xyu>oAc}{$S82Vna=^$e3x( zNnJ{|FLq-v;pLn0POw&M=u_oh!`Un=G zBSRL^D%QegdqMXj-}((}61W0T_Z7R;xRs!eV19PT8I}kf8$bjQsoHa{`B12%WhlTr zZ#a(vT;a{+p?^c5!=iu5fyVRXY4zwoa}mI21TKq{`FC5krj5~&DTaAq`Z592>dPH` z{;+#eNX;Q)n;%LqDZL~0xKx=3MW{0?2c+ySI7sA~2+qRIq+P&xgly5@hF>tVi0z9} zNrkS%xd^3XWR!}{OO&^j&`5?*SkmsE)?>%Wed}k%Yo^vK7J61PaTX;ZiULcaDUd!Ig*DT929`e2v14 zrZgcWUwRyvj^~iTq&q;N-`G-F#<~dQa3+KObT(}ZCX~!F5tbd`ks;8 zN#BsH$@NN*^Ms=fZ89|NAQ+=dsm&~aHWCP=1Q4h@&rou@_-(?sB@co^yj&ZY%0zGv zqUtg=dkPX23__3Xp5QSVeud$-a5WM;NQDb7aV_a%5l+9W%q_-b50R$K}>7o6jR6zbr(=^17dQ6y!DXvA?CJ<+!87MS|N?}(n%A9VC2AMG1f02<*D81;xRkN9#wzU(oy4+%r7e%Nuc_qZqJ zX@jNW?oTj*+!KzN98yV`NYGcpMD_=abCSLV@dEWRL+Ki;f|aVPdJBV*V&)W;Z6#ky>~iic$-$*HA6gMW<44bLK0C z>N28LV&`eA()1ufHno^h;}8T~&?**K6SX3KjKDm^N{a3Tm2fiH8PhHfqc?Obd7+=V zY&()e#_kBVycX*jhqL zIpPjQ@odLXsajBam!Q@ak720@ZKW!UVu=c-d0H;!X-$CcHV2D@URY9}E`W#! z2b96%=AZ5sLSrl5JkV*QP+_tI`@+{l#$W#A0Gcd4Xq8DQ8s(D_9WFzXufBE&l8hd- z=~Ny?zL7t6)k?0!U+SQGh&-*HBG3GrCislV!-zbP_B=?)Lq00M*lKel1VN#x5&wLU z@lTHhjSCB^PCDN6Sofq{D3wV0q}`VJG)#x=t*#5O-yvJv1kw@P^vaeNaT73lHx?4p z65IQw*Q8n<3=}y`b8Pt~O~U%iK3%9^r7}RK2lm#3{d!;z9)755r#c;)UVkq$qYF{5?~5|GNebrVKKY>Ii>5; zJV6`yQ<}qMCaVfv1~c!vJ&0&c=ZQ31M^jS%3@*25&dxMmaC?)lLaeb?+gT~@lozGS z1=SkcL4y8~%JE96BWIm%2#4&-P}s568HSxBRSIekYdna{%4!%;Jv?2(YIdSq$$KF# z+2~jBh3Uz79-&5D2s`ZtJ0xS7M(eGnabw$?aygbS=oxAJ-pvIKz6^< z2iIYT%E;|yV%W-y(B|Ej*%f;Pvni-)ttj&jLysti-iOeC+l0H?#2?a!e(*%SUAyOi zk0TTuq2TF7!F;s&87m`?0CL0=K={?(cG`G?M`B+tB)0k!j<&wgJt>u?{CQaEZJ++@ z-A_qL>-i)u7Lndwgh*p+KT9lvhN}eft>INLdzxZWXqf?tp{WrF5G&OzreP5h0D+JT zX0Ri$cO3k#g&2iq3~sE|^cTrxDd();fl9)t60o#BD9slT2EjHPFwJ%9;NlQo)$&RM zs+7BO<8MxTS))!ch+y#;7XgNOVfmp0_?0rvHxFQ%G0aqi<=yPB^2g5L^(J?%C-pK{%{;q*aIW8U{;m9iq08sNUQ>nV!vYx9KX4H7UiYN1 zF&O2gVlc{mQL+ZQo8IBnS6E8hsVPem1x1@U(HiJ%&D&ZF65(|yp}`^>C=H^aRHA7R zp&f=YKn=QJ$9aEn2I!?O6CJoG$btKCAoj0UQNd2JhlZz1 zS^a8iNXqid11JkheVc>N2VNZ~LsI@fUVa`)xmf1#Xvsea$XG%AuN}PnnLMq5@%#yh z4jw_$(2$gW`ERol<)-uhWY-WyJ(&Nd!2HYzGU0+8p2nF3uz${wh`}tSdlEHuOD9mc zsNG2@H-fM1XNWHh8)OJc5#Ciu#UfIw<&Yl>KX+$8n)5~b(XQ<@m8sCTj0i@ zY@=wE@$Pbz9-BAOec~3;YdB2_96(lG2<7 z0k>+!!PyVFCxy5inuAt}4vq&)uw+~Ac-aCLOJgm22kp)kkM%JvSv#Dka(~@~XKM*g^zivwHY?OLT3*E`rhr#>@gdkgOVT z)=~kHqp`&Hc?gPAwJhZ#Qo5@4DkH|e*l>1$GiN7IFYk+dUea>BM{w=)UqUO8K^37RW zfdg9a=07Vp-#rKKNAJ|v03GY9*Wn+<&`aHu-tb@yoq4I0Tmkf;_IAfci~(CD&c{S~5ihL= zC6MM3 zNpWy6FX+BkWEMv}MLUA6Hf08LErhy&e!5pu`k4xBsq>@}Ef(xgP^V@B?s%#AB5A$S z8pE}1B+V2$E%bGX6=q0B8wCQp^iOl7IYWt$H1VI{Y3$lftnm(a*W+RH%_(|lZ`!& z853>~8IBkV%rK507o<-6k2UQ0zM3>Ze+4(qutLvY4M1GDR(cO5A9!@Q4A#Dpmy?IJ zSNcDgJZL`0t@%87S6?2~jHNdZbjClBS>Io6!Nhwz`1d$kDv zm+n&kSf17Z;s5Y_xas_R`Lsp)`&Y5wqh|?Vd+_mffsgL_af@nH`bq}Kb12sb5R?SA zKbUUG8){AwZxW0t>{^@}M#Qe7ZNNZQOtPEpjb_Y2q+l`-WRs*>3zwiQ7{Z27ezu-w z3%enx7`iOO!8N2Z@jnNUCuFmwd(TG#9V$bdu6WoG#OX3SjR$%U;}2aJ*5&w1@9(>7 zMVfwn1yns7FEjt}KW8b>Ikl}+!q_O+U44SP=fFMbji-3ZC(SzM(=gfI&*+=&ZSBAl zrdBDtMN0BF&@JvDmu8~FD)}bw+Z)5n`?h1)dZ*HHl4;;}36+q+$FZ>PJnr^wT3$qGLqm8KBAIbZ7}<@y}-$LTVTyG$$n zSUp+@=ax`2jh;AIZKTG}MpFP7GNJq^5aV_|s?)^}Dh+~rOcN_yWnl=E5H8_VgPBNc z@PZ4pTX9YDm=O~wzm>~1-aH*34X{P^CSyv+N;cycAuRiF3PdNGwF(ljbSZG@*&4@a z@|xHL5nDbN!MOn}{9FxRrgn6qdIU0ys1XDud2gYD2X9Ot+5V%XI(~b|fL7y)4Y^fAAQ7W0i5kbhxTU5o( zP~v?Y$4*d|m%SnE=SbH^V@(apH^~VoqTGs^pogQx|M(NG*TgZZpMq)MrU)_CQaGdu z{U|xbImr`cuNtrc^Ia=mXoYn+CF)K1LQI7x4!&9Vuge+7S2os3{TXA%p@COvoinz9 z#o$Twuj*2C8K{{R#K*{bu?SiOP^v4f-zDk>@@x_qBo_J4md(QFAtFRAR1?rs952wZ zWB5D`fVDVgx|{@;!ig%uUr>d4A3OlYcUo}(@Da68NE;=grDm5bp9QovzH{qlscf}% zGd8>jYg{5g;Rjm&%e}mW)IWh?X~|(~XUh#S1t^9ynZ*wziHHk8oi+djj=Qy3VR7eX z4I&KgyoH3rdZb0j#F@OZo}r0;|2jaPfV$(OZ9Y@e!7>s>L|U`*GBiKFkWS>u6m=m} zR^2H&YIToNtNT`+Azub<8WE!rF&Ysg)*?K;#3-M9e9_3nGxH;~v@(K<2qOsrJpx7& z!rDs+9<%*1VYV|PmN=5nNAmdtBcGde(ida|TbfA@s)*aKC<#oQ>KuS#l0f}}-p3Rb zqoue?&H9e<(a>X~{d-U~M1SLAR)Z~2P6}gNH`f~|18|tNlVd2r%twLxTdUM7sE0gF z^&0;(4F>T>cs#Dq;t5rxf*vr?n3}9B%s8{Q31y?=mZ0+>zM5<%8;3M;eq(@2a(%zO z=SvnkWJWQ06A50PVsdTvs6C4L%R(`&dh+w`7GI-xw`%pI>jFa0;!Djx{C_iI-MO)y z)JXOrx!&rB-MzlYJ?RY(#?zUt65s0Jr!HnL4^xjWxz z0l!*+*wR7LHFmWX@m*U^SgGA^7$X2vJYb~#~J4(;?I^N|JFRW85M#&==q4!F=11E;M2!&=~36JbDV`syi)+p5t<1Xyip z*dVG)Zz#jAKUSUbE%bLw4cqQjXqT9Rc0PU9u`-PLn(K#P%$K`)JkoU&f9c{BuEJj$ zr|?jDS_78+N?`8@Uq|?Ady<|}e9cF%|FYuG2yRDw=B(i}9>Javf?b_*l=>F;q%=E6 zn!3qKQ`0*b@IY~DzvH0F;#7PP-CMemIVnj54Gk3Jn^sz)kA54~^pzwg)9`o&iAf@z z3#R&;`1r-NCas)J)Cxl-*eH#Oo09MVJArY}i6m!4Lll0~8ge3E7->i(F3LnG0gQkc zNQ&IH$c9GqM)HLxYec1uPvp>IVgzv;Jq3$Z-jbO(vzZ6774li7 zDKvx>t$YI^1LL9;mTboeD(ETDK*MS)!PG+ZBUeGuHV74g(@Jj|uA%`voX&P&t0253 z!ArGhLN6AlIL7EMm{QoRTMsov{b{s4+c>N+vu=PegAfVKC-DavDv(zPMIi6Wc0kG zq4XG~GqP4W=7p%5+P34t6Uol+>(HU7b3;-9|9-N@p_-4#xL4+u8rOL90H%#RiFC8W z4wYfqZ{_8zya?0v$4=wnz^}=zT88~*ce$_A%U!+G@GWQi?d6~NO@@th&;Grn==%F| zvDJ^b8-1U9(z_)g>*_7{bL&4>ppt0E&bmGp!iU$cG^D|ZTJJU_ZS){(Z3xCp%=AXO z>=#==8$M8rgC2pl0z=o6dei`PL46m%ak{Yl`_s`f81pwgpFE7Y!kfuMnlJFT&S>{p zcd&o1$GLi>+2xRCHHV#lGT&z*dyOVc!S7pgMAdJ*v-ubIq^Fbvez!`nH;&&jfdinn zEjEd^pE>nR)Z?f%to{@XhAl*X+ZkqO^G{Gm%fQyU8-{@`Zzd16ZsuaNc}$)UHsWvJ0osF;$?RkyfZJ>EU({&Jw=X%;F{^e_0^u^)f0u<_Uduz@;u zdSiByVZcKN%z(!po~U4?>- z##RJ=#s&wIlatN{X1d-;#a4ceiPNu#B}^Lz03Ygm^lm8s^mVul=)Hson+JMV`crv; z_e!}H3wS^3uB0PRYXEpZ;sf3TeM|W#`gqGN&+Ix=GCXicXXS)MQeSrBoxY+EN^cfkb+sKNgY0Dslhbm$D?e1J!thd9?{ zruA^=BmBK%>%Z&n={MwQ4RGg2ecU+%_m+=7n=JaA@uj91^jW!<>fgBg_@sN%n;DEj zGlwLoGHxw^Auw116<(k!9cWch>=V4im8Wsu6|W_6T0|<1XQq#%5S>7zWCHge{0H}3~f>wf47(kNgBrZSb+b|?L?O}CNyKoBJ97vY3c0-cwUtm(QQ zBR+%)&g6$$1hs`6Y2;K`fm$( zS&sRy4z~VLo>q_bGd~FU8$sKupe-LTCJo^loi@D)tHW&%Ij*^pEU~%{|EP+4iF;D~ z$f3O-6Hj`v1FL{Xdv|o;35F5ak`r4}y@yKrq<05u0n{Q%nD0U36-cjSo|uXQ2p$)w zw0gZ=@c`|;o6=lI^@?$ml@nZTWJAy?D;X+?ycJS*Mm9zjA&ZuJT2d<&1lWBuEJ^(Y z+N0sEZcQ!1v))9@i3Fi}377!l4}llFEiW*Tze8;yun^e?SVi2D!p$gJV40TEaJvwY zZ;Zh@&dnwG+Obj=wOGaw@O>TOpvoL3gWU*^Gz>s}`F5*z7O*z8+ek0b4O3-=7EJMf zOMG)mZ)<}o80|3(EMNoPD^#KH_8NBp>q_!5zW~ zs(Ty<_yPB%ydX!qyI(YGh<4!Rs#WhXt;<~tTJRtd^_--o7Tez1uM)IK9X2VTC=p65 zwWE47Zm~)9P2v=2sTL2 z@Sq@{it1Pyp(Z3W<_R^IyLmh~t_U1kf##?K;=AN&4FsCs0icgS8|EP-7N1L?oezn( zTYmnY(G`ca&gr<~qdvj%pVxwTc~sy>g$m4!aP{0|LniU{c!qlCh#*fB5d_`3i^o`A zpoOXjOTzQDo(K&6hqcd*7=a)Glp`3U5FDl5^yG)Met6{xWDK=@zX1Md%M}#4 zL`C`I6@-e?=pW*9u>NTu5-F3g&p><;Yd*74nJ~=Sk}yhjnwpr&klv(G2LI(9}7cq0)xPY}3y#d$rF@HQa{Rxo&j1Fcud(;5f{ zj{x|M01TnGeE}^0{-15x@8}>Adx;#Q6%I1>hQ41wy81x}%fIEG6siXk%x*k8tC~?c zs=?^YdjpZ&UMf{+(uO}2b?J*t$7l8x`8`4mqtkF;Eyoz9~upOfRa6y-17+5fRTt)8NE z?>TK(k$+@|3^tz5MWm4YbverFzqvE~ihI)291O`bZx`PZ^ucg0sUrlM@y}6Xp6|MDae;hLMYhZ2=Jy^o%9Cbm&)pq1qi(#tQEc# zuwi!4B%dv^EK^~F9bp42rV*bkSGEF$vd6V(p#6~Wo5w$DX~L=ay{JTJ{i?c0(J z2@LD)Yb85iNhPE}q5`!p2Sd4@63B8)7=_ERy}lAS3b?Cc)B`DD=Or7OV7)!*CRth8 zoN1b_LLtZ1>5%5RCSJlU&Td_f38wG)ko_#IC>m@<5pJnwrN?MUi`0_g zHdb9Img5RT7o@rb8)aZG={d+9;2_atZ>fRTAA+PiA6-j%^ZMbt>qu|~mZh7dJeSb$6e3fl-LB#H zEYCG81)Lo~0g*DAUdb>{BONS5`wBM=LHoSB_o&`={HcqKx(t7*H~7ESi0aLp1TK$| zmknV?$a^*+Z$8g_u9aX%AZ&XYjX?OU0^wBR8WS>J-Q?)^qurBI@*IilPBFHC6(I{2 z^%fvhl~nGUh66}rVgh_%L@*;5@Lk4>K)#4-C95}-Vz7G_$_nS_Au4HM28txCGzn1+ ziD>!*`dVyROGeQwq1+@YN{al%S3?O?gveKrN&1OO)J6Dev(rK_C8B8Nt*pceby*P9 zC^Hp$E%v2wgsCuW84qf{O?o7?vnnh(D?bi4W4EIfWse zE(-&s0_a7{uOgpd>5v)O;C4bru3nU#&XW+H#Q~gz@Jt6+PnM_E>qSx;bp&Ro3TFA> zP_+DuwP!~Me98x$QrB5Qf$E%t{kz?hV!>eQ+Wm^)Gj)}=l2deUqEfs3Qb^EPrpM}u zqTql;9bmI2RS!w;oLUutix+}p(bA%XCGs_>p`5RcPD0dzgxn?UTO~^AF|AXKgp;H*e7WBG0Lph`|C7oG zb{#ZB`(D6%%cFhQf%avt#-n~Om8-W_p%d=j8}hVz>eu~?^9%^`uc~V3()qXblw!O= zz^3{}2QRO7PYOAMDaOn-B9CdO@4aY=-a%bfTEWbtnry_b>vFvo%Lvq!Mse2uqd$j4 zWIMB~1xH1kI?Yt|unjXXtStyqp=nJUe4}cLOz6!5;YKXO_dw=>k)+UGYDU3&Z-QjK z+LhHvf}y8DHmt2kBD6u43}wHZ{TwYivmd5EtYSXHPUA zT6Mq-VR<*NH;=Gf-8-2_R6Z!sVTsDS9BBNqJgosy`Hu%NpyXd^(-NQu^)aQy>MsQx ztDkak_$Tg3A#yOW>i(m}D>yiIAjP2_Nf*>!=TqDit2w0zS8a)S?$Ho>sSp^bGz?{$ zDZk)-v>~BI-noF-(&9;lucYs#<)X8P$8H*<22*4maqqz#+cowKh1$7!HCd4T} zL6vd>KK9$xQD2#x((w^;cNjT(=2vr_g~C&wvh|5uo-{1|SsFlp9=_5!<%6sao1sGg zoA;JSg|63q^2%=-a(}KVlsvj%Uhd_&riBQu* z<}B5f8f-{xAksj9ulUha>Zqd)kxAz*ML=qJY@!CT`tO)$s zuxR&V1JDjN`_f~|hYuYpgKp2`Rpp`EWp)}5&F18eEt<`^3*IkJYk+2deSY41{yn|e z;_>-<0x6+5AwX1pfrFmdJt-XJ5Q=Zi&ekCC6Jd zA&?m_Dfvk2EQvvp-9seKtBId6JPe9E2kspTtwj=KxRmBVB7_cXWMXp#!6p)Ji=OFe zoe7t6OJ_+@SuX=Vgj~?VDUI))-O?o6Ocs2TfeucKL5#jMh;13V!rUtd5Dr)Xvd5MW zmO5aDe7uGim`6UY?w!mdB5#!Yw?yQp-Q~Yrp4Nbf{KNSU4f*%>a!XFm|FcL5%ew@y zs_%9X^(*d4VQVm9nR&Pv9s#!%pS0{lThDr@?g$Bp0lW+7HM$Y5i1s2nB3Vx^I6P2R zGwy6aUO`$NtwemBzu5SKwKEh*1jZB!D(3PQXov-1;e4(+%QE-bXr9}#6yrJ)hZPLL2uHw5uiTeE3`imPJp zbbXwHTQ>)XhZS62J%Ik8Fiz%Z^TAlh%aEUs^P2O>&s9BhdDQ1q0wk9De9S?}hvjMY z)Mw^mK+ymC9e##^}#xP3P?h zN`=1#G#BB=rDE7B9n^hpGc+2zL@tq%UwZ`707kq&h)ZPfa4_GHKgY})s(JRWS` z7#N=qDzT$)3fwep^uv~xgY6K67I{=y2)@vkwK7&I?jVsse*nQzf5^kt=pPON`wX4b z_>g%KycSqqeE|@MB#GLS!7eRjwhd*=;LP^!F}SU8WYZ+7eQw*jIaq&Wlgus4NG6YL z+IH*a^+U$u{PzJQ8z!FYyu-xl>W~?#{g9i7pxW1Fr}OZkzyVw=&IR~Ojd0&wE5iL1 zAj}9ifV}5FZsfD3*I3r{r4dwU%dGPNDpG>kLobC~dXy#*N;5N}2VnX1ESv{7pTjFn zmiA2b^uZ8t99~sEAf=6s{mAF~>*#l#HwXa+OsX5!}Yq#5M$?I@7TcT!x@D z6_S!p6Xjx1tF%`*a8bIq4y%>@!T=VpRv}%r*+V{Y)B!UL{^`V;JhhBgA#XAd>2?Ux zS-tFO?k1+>Y4v(pxBh@$P5vSNyx}kp^ukhm$vtx9)#tmjKIoqG)N|k;weEYbleX6^ z4x|AOw0;i82F7|8GU$Mx3`7SfD-S8}zI6aHAOf@BhVt)H2hAWv!sE?Di0hV5=pn@q z%MDqixX)eBf;_DOQlRdGN3R~RyUIV&w^-~rQ!7l-?;%AKK526@ zJ`K~XZCpxSPtb|zb!wYv#1oY|!hPBkabp5VGa>3U8noSb@5%0D`Ws)1Xa95k5fo*? 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�^yee{@))?vt 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 G?*9++FU?*6 diff --git a/src/doc/user/sphinx/_build/doctrees/usermanual.doctree b/src/doc/user/sphinx/_build/doctrees/usermanual.doctree deleted file mode 100644 index 541befb098eaf8a29772df240a360ceef7d586c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1030673 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%0D^A#16N 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 Qb)sp;BZ_8fwZ6{(4@In$M*si- diff --git a/src/doc/user/sphinx/_build/html/.buildinfo b/src/doc/user/sphinx/_build/html/.buildinfo deleted file mode 100644 index 4cafcd3d..00000000 --- a/src/doc/user/sphinx/_build/html/.buildinfo +++ /dev/null @@ -1,4 +0,0 @@ -# Sphinx build info version 1 -# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 231f945ed2862c51951e13914a8fee2b -tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/src/doc/user/sphinx/_build/html/_sources/source/usermanual.txt b/src/doc/user/sphinx/_build/html/_sources/source/usermanual.txt deleted file mode 100644 index fe0c4adf..00000000 --- a/src/doc/user/sphinx/_build/html/_sources/source/usermanual.txt +++ /dev/null @@ -1,6006 +0,0 @@ -================== -Recoll user manual -================== - -:Author: Jean-Francois Dockes - -.. contents:: - :depth: 3 -.. - -Introduction -============ - -This document introduces full text search notions and describes the -installation and use of the RCL application. It is updated for RCL -RCLVERSION. - -RCL was for a long time dedicated to Unix-like systems. It was only -lately (2015) ported to MS-Windows. Many references in this manual, -especially file locations, are specific to Unix, and not valid on WIN, -where some described features are also not available. The manual will be -progressively updated. Until this happens, on WIN, most references to -shared files can be translated by looking under the Recoll installation -directory (esp. the ``Share`` subdirectory). The user configuration is -stored by default under ``AppData/Local/Recoll`` inside the user -directory, along with the index itself. - -Giving it a try ---------------- - -If you do not like reading manuals (who does?) but wish to give RCL a -try, just `install <#RCL.INSTALL.BINARY>`__ the application and start -the ``recoll`` graphical user interface (GUI), which will ask permission -to index your home directory by default, allowing you to search -immediately after indexing completes. - -Do not do this if your home directory contains a huge number of -documents and you do not want to wait or are very short on disk space. -In this case, you may first want to customize the -`configuration <#RCL.INDEXING.CONFIG>`__ to restrict the indexed area -(for the very impatient with a completed package install, from the -``recoll`` GUI: Preferences > Indexing configuration, then adjust the -Top directories section). - -On Unix/Linux, you may need to install the appropriate `supporting -applications <#RCL.INSTALL.EXTERNAL>`__ for document types that need -them (for example antiword for Microsoft Word files). - -The RCL for WIN package is self-contained and includes most useful -auxiliary programs. You will just need to install Python 2.7. - -Full text search ----------------- - -RCL is a full text search application, which means that it finds your -data by content rather than by external attributes (like the file name). -You specify words (terms) which should or should not appear in the text -you are looking for, and receive in return a list of matching documents, -ordered so that the most *relevant* documents will appear first. - -You do not need to remember in what file or email message you stored a -given piece of information. You just ask for related terms, and the tool -will return a list of documents where these terms are prominent, in a -similar way to Internet search engines. - -Full text search applications try to determine which documents are most -relevant to the search terms you provide. Computer algorithms for -determining relevance can be very complex, and in general are inferior -to the power of the human mind to rapidly determine relevance. The -quality of relevance guessing is probably the most important aspect when -evaluating a search application. RCL relies on the XAP probabilistic -information retrieval library to determine relevance. - -In many cases, you are looking for all the forms of a word, including -plurals, different tenses for a verb, or terms derived from the same -root or *stem* (example: floor, floors, floored, flooring...). Queries -are usually automatically expanded to all such related terms (words that -reduce to the same stem). This can be prevented for searching for a -specific form. - -Stemming, by itself, does not accommodate for misspellings or phonetic -searches. A full text search application may also support this form of -approximation. For example, a search for aliterattion returning no -result might propose alliteration, alteration, alterations, or -altercation as possible replacement terms. RCL bases its suggestions on -the actual index contents, so that suggestions may be made for words -which would not appear in a standard dictionary. - -Recoll overview ---------------- - -RCL uses the `XAP `__ information retrieval -library as its storage and retrieval engine. XAP is a very mature -package using `a sophisticated probabilistic ranking -model `__. - -The XAP library manages an index database which describes where terms -appear in your document files. It efficiently processes the complex -queries which are produced by the RCL query expansion mechanism, and is -in charge of the all-important relevance computation task. - -RCL provides the mechanisms and interface to get data into and out of -the index. This includes translating the many possible document formats -into pure text, handling term variations (using XAP stemmers), and -spelling approximations (using the aspell speller), interpreting user -queries and presenting results. - -In a shorter way, RCL does the dirty footwork, XAP deals with the -intelligent parts of the process. - -The XAP index can be big (roughly the size of the original document -set), but it is not a document archive. RCL can only display documents -that still exist at the place from which they were indexed. (Actually, -there is a way to reconstruct a document from the information in the -index, but only the pure text is saved, possibly without punctuation and -capitalization, depending on RCL version). - -RCL stores all internal data in Unicode UTF-8 format, and it can index -files of many types with different character sets, encodings, and -languages into the same index. It can process documents embedded inside -other documents (for example a pdf document stored inside a Zip archive -sent as an email attachment...), down to an arbitrary depth. - -Stemming is the process by which RCL reduces words to their radicals so -that searching does not depend, for example, on a word being singular or -plural (floor, floors), or on a verb tense (flooring, floored). Because -the mechanisms used for stemming depend on the specific grammatical -rules for each language, there is a separate XAP stemmer module for most -common languages where stemming makes sense. - -RCL stores the unstemmed versions of terms in the main index and uses -auxiliary databases for term expansion (one for each stemming language), -which means that you can switch stemming languages between searches, or -add a language without needing a full reindex. - -Storing documents written in different languages in the same index is -possible, and commonly done. In this situation, you can specify several -stemming languages for the index. - -RCL currently makes no attempt at automatic language recognition, which -means that the stemmer will sometimes be applied to terms from other -languages with potentially strange results. In practise, even if this -introduces possibilities of confusion, this approach has been proven -quite useful, and it is much less cumbersome than separating your -documents according to what language they are written in. - -By default, RCL strips most accents and diacritics from terms, and -converts them to lower case before either storing them in the index or -searching for them. As a consequence, it is impossible to search for a -particular capitalization of a term (``US`` / ``us``), or to -discriminate two terms based on diacritics (``sake`` / ``saké``, -``mate`` / ``maté``). - -RCL can optionally store the raw terms, without accent stripping or case -conversion. In this configuration, default searches will behave as -before, but it is possible to perform searches sensitive to case and -diacritics. This is described in more detail in the `section about index -case and diacritics sensitivity <#RCL.INDEXING.CONFIG.SENS>`__. - -RCL has many parameters which define exactly what to index, and how to -classify and decode the source documents. These are kept in -`configuration files <#RCL.INDEXING.CONFIG>`__. A default configuration -is copied into a standard location (usually something like -``/usr/share/recoll/examples``) during installation. The default values -set by the configuration files in this directory may be overridden by -values set inside your personal configuration, found by default in the -``.recoll`` sub-directory of your home directory. The default -configuration will index your home directory with default parameters and -should be sufficient for giving RCL a try, but you may want to adjust it -later, which can be done either by editing the text files or by using -configuration menus in the ``recoll`` GUI. Some other parameters -affecting only the ``recoll`` GUI are stored in the standard location -defined by Qt. - -The `indexing process <#RCL.INDEXING.PERIODIC.EXEC>`__ is started -automatically (after asking permission), the first time you execute the -``recoll`` GUI. Indexing can also be performed by executing the -``recollindex`` command. RCL indexing is multithreaded by default when -appropriate hardware resources are available, and can perform in -parallel multiple tasks for text extraction, segmentation and index -updates. - -`Searches <#RCL.SEARCH>`__ are usually performed inside the ``recoll`` -GUI, which has many options to help you find what you are looking for. -However, there are other ways to perform RCL searches: - -- A `command line interface <#RCL.SEARCH.COMMANDLINE>`__. - -- A `Python programming interface <#RCL.PROGRAM.PYTHONAPI>`__ - -- A `KDE KIO slave module <#RCL.SEARCH.KIO>`__. - -- A Ubuntu Unity - `Scope `__ - module. - -- A Gnome Shell `Search - Provider `__. - -- A `WEB interface `__. - -Indexing -======== - -Introduction ------------- - -Indexing is the process by which the set of documents is analyzed and -the data entered into the database. RCL indexing is normally -incremental: documents will only be processed if they have been modified -since the last run. On the first execution, all documents will need -processing. A full index build can be forced later by specifying an -option to the indexing command (``recollindex`` ``-z`` or ``-Z``). - -``recollindex`` skips files which caused an error during a previous -pass. This is a performance optimization, and a new behaviour in version -1.21 (failed files were always retried by previous versions). The -command line option ``-k`` can be set to retry failed files, for example -after updating an input handler. - -The following sections give an overview of different aspects of the -indexing processes and configuration, with links to detailed sections. - -Depending on your data, temporary files may be needed during indexing, -some of them possibly quite big. You can use the RECOLL\_TMPDIR or -TMPDIR environment variables to determine where they are created (the -default is to use ``/tmp``). Using TMPDIR has the nice property that it -may also be taken into account by auxiliary commands executed by -``recollindex``. - -Indexing modes -~~~~~~~~~~~~~~ - -RCL indexing can be performed along two main modes: - -- **`Periodic (or batch) indexing: <#RCL.INDEXING.PERIODIC>`__.** - - ``recollindex`` is executed at discrete times. The typical usage is - to have a nightly run `programmed <#RCL.INDEXING.PERIODIC.AUTOMAT>`__ - into your ``cron`` file. - -- **`Real time indexing: <#RCL.INDEXING.MONITOR>`__.** - - ``recollindex`` runs permanently as a daemon and uses a file system - alteration monitor (e.g. inotify) to detect file changes. New or - updated files are indexed at once. - -The choice between the two methods is mostly a matter of preference, and -they can be combined by setting up multiple indexes (ie: use periodic -indexing on a big documentation directory, and real time indexing on a -small home directory). Monitoring a big file system tree can consume -significant system resources. - -With RCL 1.24 and newer, it is also possible to set up an index so that -only a subset of the tree will be monitored and the rest will be covered -by batch/incremental indexing. (See the details in the `Real time -indexing <#RCL.INDEXING.MONITOR>`__ section. - -The choice of method and the parameters used can be configured from the -``recoll`` GUI: Preferences > Indexing schedule - -The GUI File menu also has entries to start or stop the current indexing -operation. Stopping indexing is performed by killing the ``recollindex`` -process, which will checkpoint its state and exit. A later restart of -indexing will mostly resume from where things stopped (the file tree -walk has to be restarted from the beginning). - -When the real time indexer is running, two operations are available from -the menu: 'Stop' and 'Trigger incremental pass'. When no indexing is -running, you have a choice of updating the index or rebuilding it (the -first choice only processes changed files, the second one zeroes the -index before starting so that all files are processed). - -Configurations, multiple indexes -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -RCL supports defining multiple indexes, each defined by its own -`configuration directory <#RCL.INDEXING.CONFIG>`__, in which several -configuration files describe what should be indexed and how. - -A default personal configuration directory (``$HOME/.recoll/``) is -created when a RCL program is first executed. This configuration is the -one used for indexing and querying when no specific configuration is -specified. - -All configuration parameters have defaults, defined in system-wide -files. Without further customisation, the default configuration will -process your complete home directory, with a reasonable set of defaults. -It can be changed to process a different area of the file system, select -files in different ways, and many other things. - -In some cases, it may be useful to create additional configuration -directories, for example, to separate personal and shared indexes, or to -take advantage of the organization of your data to improve search -precision. - -A plausible usage scenario for the multiple index feature would be for a -system administrator to set up a central index for shared data, that you -choose to search or not in addition to your personal data. Of course, -there are other possibilities. for example, there are many cases where -you know the subset of files that should be searched, and where -narrowing the search can improve the results. You can achieve -approximately the same effect with the directory filter in advanced -search, but multiple indexes may have better performance and may be -worth the trouble in some cases. - -A more advanced use case would be to use multiple index to improve -indexing performance, by updating several indexes in parallel (using -multiple CPU cores and disks, or possibly several machines), and then -merging them, or querying them in parallel. - -A specific configuration can be selected by setting the RECOLL\_CONFDIR -environment variable, or giving the ``-c`` option to any of the RCL -commands. - -When creating or updating indexes, the different configurations are -entirely independant (no parameters are ever shared between -configurations when indexing). The ``recollindex`` program always works -on a single index. - -When querying, multiple indexes can be accessed concurrently, either -from the GUI or the command line. When doing this, there is always one -main configuration, from which both configuration and index data are -used. Only the index data from the additional indexes is used (their -configuration parameters are ignored). - -The behaviour of index update and query regarding multiple -configurations is important and sometimes confusing, so it will be -rephrased here: for index generation, multiple configurations are -totally independant from each other. When querying, configuration and -data are used from the main index (the one designated by ``-c`` or -RECOLL\_CONFDIR), and only the data from the additional indexes is used. -This implies that some parameters should be consistent among the -configurations for indexes which are to be used together. - -See the section about `configuring multiple -indexes <#RCL.INDEXING.CONFIG.MULTIPLE>`__ for more detail - -Document types -~~~~~~~~~~~~~~ - -RCL knows about quite a few different document types. The parameters for -document types recognition and processing are set in `configuration -files <#RCL.INDEXING.CONFIG>`__. - -Most file types, like HTML or word processing files, only hold one -document. Some file types, like email folders or zip archives, can hold -many individually indexed documents, which may themselves be compound -ones. Such hierarchies can go quite deep, and RCL can process, for -example, a LibreOffice document stored as an attachment to an email -message inside an email folder archived in a zip file... - -``recollindex`` processes plain text, HTML, OpenDocument -(Open/LibreOffice), email formats, and a few others internally. - -Other file types (ie: postscript, pdf, ms-word, rtf ...) need external -applications for preprocessing. The list is in the -`installation <#RCL.INSTALL.EXTERNAL>`__ section. After every indexing -operation, RCL updates a list of commands that would be needed for -indexing existing files types. This list can be displayed by selecting -the menu option File > Show Missing Helpers in the ``recoll`` GUI. It is -stored in the ``missing`` text file inside the configuration directory. - -By default, RCL will try to index any file type that it has a way to -read. This is sometimes not desirable, and there are ways to either -exclude some types, or on the contrary define a positive list of types -to be indexed. In the latter case, any type not in the list will be -ignored. - -Excluding files by name can be done by adding wildcard name patterns to -the `skippedNames <#RCL.INSTALL.CONFIG.RECOLLCONF.SKIPPEDNAMES>`__ list, -which can be done from the GUI Index configuration menu. Excluding by -type can be done by setting the -`excludedmimetypes <#RCL.INSTALL.CONFIG.RECOLLCONF.EXCLUDEDMIMETYPES>`__ -list in the configuration file (1.20 and later). This can be redefined -for subdirectories. - -You can also define an exclusive list of MIME types to be indexed (no -others will be indexed), by settting the -`indexedmimetypes <#RCL.INSTALL.CONFIG.RECOLLCONF.INDEXEDMIMETYPES>`__ -configuration variable. Example: - -:: - - indexedmimetypes = text/html application/pdf - - -It is possible to redefine this parameter for subdirectories. Example: - -:: - - [/path/to/my/dir] - indexedmimetypes = application/pdf - - -(When using sections like this, don't forget that they remain in effect -until the end of the file or another section indicator). - -``excludedmimetypes`` or ``indexedmimetypes``, can be set either by -editing the `configuration file -(``recoll.conf``) <#RCL.INSTALL.CONFIG.RECOLLCONF>`__ for the index, or -by using the GUI index configuration tool. - - **Note** - - When editing the ``indexedmimetypes`` or ``excludedmimetypes`` - lists, you should use the MIME values listed in the ``mimemap`` file - or in Recoll result lists in preference to ``file -i`` output: there - are a number of differences. The ``file -i`` output should only be - used for files without extensions, or for which the extension is not - listed in ``mimemap`` - -Indexing failures -~~~~~~~~~~~~~~~~~ - -Indexing may fail for some documents, for a number of reasons: a helper -program may be missing, the document may be corrupt, we may fail to -uncompress a file because no file system space is available, etc. - -RCL versions prior to 1.21 always retried to index files which had -previously caused an error. This guaranteed that anything that may have -become indexable (for example because a helper had been installed) would -be indexed. However this was bad for performance because some indexing -failures may be quite costly (for example failing to uncompress a big -file because of insufficient disk space). - -The indexer in RCL versions 1.21 and later does not retry failed files -by default. Retrying will only occur if an explicit option (``-k``) is -set on the ``recollindex`` command line, or if a script executed when -``recollindex`` starts up says so. The script is defined by a -configuration variable (``checkneedretryindexscript``), and makes a -rather lame attempt at deciding if a helper command may have been -installed, by checking if any of the common ``bin`` directories have -changed. - -Recovery -~~~~~~~~ - -In the rare case where the index becomes corrupted (which can signal -itself by weird search results or crashes), the index files need to be -erased before restarting a clean indexing pass. Just delete the -``xapiandb`` directory (see `next section <#RCL.INDEXING.STORAGE>`__), -or, alternatively, start the next ``recollindex`` with the ``-z`` -option, which will reset the database before indexing. The difference -between the two methods is that the second will not change the current -index format, which may be undesirable if a newer format is supported by -the XAP version. - -Index storage -------------- - -The default location for the index data is the ``xapiandb`` subdirectory -of the RCL configuration directory, typically -``$HOME/.recoll/xapiandb/``. This can be changed via two different -methods (with different purposes): - -1. For a given configuration directory, you can specify a non-default - storage location for the index by setting the ``dbdir`` parameter in - the configuration file (see the `configuration - section <#RCL.INSTALL.CONFIG.RECOLLCONF>`__). This method would - mainly be of use if you wanted to keep the configuration directory in - its default location, but desired another location for the index, - typically out of disk occupation or performance concerns. - -2. You can specify a different configuration directory by setting the - RECOLL\_CONFDIR environment variable, or using the ``-c`` option to - the RCL commands. This method would typically be used to index - different areas of the file system to different indexes. For example, - if you were to issue the following command: - - :: - - recoll -c ~/.indexes-email - - Then RCL would use configuration files stored in - ``~/.indexes-email/`` and, (unless specified otherwise in - ``recoll.conf``) would look for the index in - ``~/.indexes-email/xapiandb/``. - - Using multiple configuration directories and `configuration - options <#RCL.INSTALL.CONFIG.RECOLLCONF>`__ allows you to tailor - multiple configurations and indexes to handle whatever subset of the - available data you wish to make searchable. - -The size of the index is determined by the size of the set of documents, -but the ratio can vary a lot. For a typical mixed set of documents, the -index size will often be close to the data set size. In specific cases -(a set of compressed mbox files for example), the index can become much -bigger than the documents. It may also be much smaller if the documents -contain a lot of images or other non-indexed data (an extreme example -being a set of mp3 files where only the tags would be indexed). - -Of course, images, sound and video do not increase the index size, which -means that in most cases, the space used by the index will be negligible -against the total amount of data on the computer. - -The index data directory (``xapiandb``) only contains data that can be -completely rebuilt by an index run (as long as the original documents -exist), and it can always be destroyed safely. - -XAP index formats -~~~~~~~~~~~~~~~~~ - -XAP versions usually support several formats for index storage. A given -major XAP version will have a current format, used to create new -indexes, and will also support the format from the previous major -version. - -XAP will not convert automatically an existing index from the older -format to the newer one. If you want to upgrade to the new format, or if -a very old index needs to be converted because its format is not -supported any more, you will have to explicitly delete the old index -(typically ``~/.recoll/xapiandb``), then run a normal indexing command. -Using ``recollindex`` option ``-z`` would not work in this situation. - -Security aspects -~~~~~~~~~~~~~~~~ - -The RCL index does not hold complete copies of the indexed documents (it -almost does after version 1.24). But it does hold enough data to allow -for an almost complete reconstruction. If confidential data is indexed, -access to the database directory should be restricted. - -RCL will create the configuration directory with a mode of 0700 (access -by owner only). As the index data directory is by default a -sub-directory of the configuration directory, this should result in -appropriate protection. - -If you use another setup, you should think of the kind of protection you -need for your index, set the directory and files access modes -appropriately, and also maybe adjust the ``umask`` used during index -updates. - -Special considerations for big indexes -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This only needs concern you if your index is going to be bigger than -around 5 GBytes. Beyond 10 GBytes, it becomes a serious issue. Most -people have much smaller indexes. For reference, 5 GBytes would be -around 2000 bibles, a lot of text. If you have a huge text dataset -(remember: images don't count, the text content of PDFs is typically -less than 5% of the file size), read on. - -The amount of writing performed by Xapian during index creation is not -linear with the index size (it is somewhere between linear and -quadratic). For big indexes this becomes a performance issue, and may -even be an SSD disk wear issue. - -The problem can be mitigated by observing the following rules: - -- Partition the data set and create several indexes of reasonable size - rather than a huge one. These indexes can then be queried in parallel - (using the RCL external indexes facility), or merged using - ``xapian-compact``. - -- Have a lot of RAM available and set the ``idxflushmb`` RCL - configuration parameter as high as you can without swapping - (experimentation will be needed). 200 would be a minimum in this - context. - -- Use Xapian 1.4.10 or newer, as this version brought a significant - improvement in the amount of writes. - -Index configuration -------------------- - -Variables set inside the `RCL configuration -files <#RCL.INSTALL.CONFIG>`__ control which areas of the file system -are indexed, and how files are processed. These variables can be set -either by editing the text files or by using the `dialogs in the -``recoll`` GUI <#RCL.INDEXING.CONFIG.GUI>`__. - -The first time you start ``recoll``, you will be asked whether or not -you would like it to build the index. If you want to adjust the -configuration before indexing, just click Cancel at this point, which -will get you into the configuration interface. If you exit at this -point, ``recoll`` will have created a ``~/.recoll`` directory containing -empty configuration files, which you can edit by hand. - -The configuration is documented inside the `installation -chapter <#RCL.INSTALL.CONFIG>`__ of this document, or in the recoll.conf -5 man page, but the most current information will most likely be the -comments inside the sample file. The most immediately useful variable is -probably ```topdirs`` <#RCL.INSTALL.CONFIG.RECOLLCONF.TOPDIRS>`__, which -determines what subtrees and files get indexed. - -The applications needed to index file types other than text, HTML or -email (ie: pdf, postscript, ms-word...) are described in the `external -packages section. <#RCL.INSTALL.EXTERNAL>`__ - -As of Recoll 1.18 there are two incompatible types of Recoll indexes, -depending on the treatment of character case and diacritics. A `further -section <#RCL.INDEXING.CONFIG.SENS>`__ describes the two types in more -detail. - -Multiple indexes -~~~~~~~~~~~~~~~~ - -Multiple RCL indexes can be created by using several configuration -directories which are typically set to index different areas of the file -system. A specific index can be selected for updating or searching, -using the RECOLL\_CONFDIR environment variable or the ``-c`` option to -``recoll`` and ``recollindex``. - -Index configuration parameters can be set either by using a text editor -on the files, or, for most parameters, by using the ``recoll`` index -configuration GUI. In the latter case, the configuration directory for -which parameters are modified is the one which was selected by -RECOLL\_CONFDIR or the ``-c`` parameter, and there is no way to switch -configurations within the GUI. - -As a remainder from a previous section, a ``recollindex`` program -instance can only update one specific index, and it will only use -parameters from a single configuration (no parameters are ever shared -between configurations when indexing). All the query methods -(``recoll``, ``recollq``, the Python API, etc.) operate with a main -configuration, from which both configuration and index data are used, -but can also query data from multiple additional indexes. Only the index -data from the latter is used, their configuration parameters are -ignored. - -When searching, the current main index (defined by RECOLL\_CONFDIR or -``-c``) is always active. If this is undesirable, you can set up your -base configuration to index an empty directory. - -If a set of multiple indexes are to be used together for searches, some -configuration parameters must be consistent among the set. These are -parameters which need to be the same when indexing and searching. As the -parameters come from the main configuration when searching, they need to -be compatible with what was set when creating the other indexes (which -came from their respective configuration directories). - -Most importantly, all indexes to be queried concurrently must have the -same option concerning character case and diacritics stripping, but -there are other constraints. Most of the relevant parameters are -described in the `linked -section <#RCL.INSTALL.CONFIG.RECOLLCONF.TERMS>`__. - -The different search interfaces (GUI, command line, ...) have different -methods to define the set of indexes to be used, see the appropriate -section. - -At the moment, using multiple configurations implies a small level of -command line usage. Additional configuration directories (beyond -``~/.recoll``) must be created by hand (``mkdir`` or such), the GUI will -not do it. This is to avoid mistakenly creating additional directories -when an argument is mistyped. Also, the GUI or the indexer must be -launched with a specific option or environment to work on the right -configuration. - -To be more practical, here follows a few examples of the commands need -to create, configure, update, and query an additional index. - -Initially creating the configuration and index: - -:: - - mkdir /path/to/my/new/config - -Configuring the new index can be done from the ``recoll`` GUI, launched -from the command line to pass the ``-c`` option (you could create a -desktop file to do it for you), and then using the GUI index -configuration tool to set up the index. - -:: - - recoll -c /path/to/my/new/config - -Alternatively, you can just start a text editor on the main -configuration file ```recoll.conf - `` <#RCL.INSTALL.CONFIG.RECOLLCONF>`__. - -Creating and updating the index can be done from the command line: - -:: - - recollindex -c /path/to/my/new/config - -or from the File menu of a GUI launched with the same option -(``recoll``, see above). - -The same GUI would also let you set up batch indexing for the new index. -Real time indexing can only be set up from the GUI for the default index -(the menu entry will be inactive if the GUI was started with a -non-default ``-c`` option). - -The new index can be queried alone with - -:: - - recoll -c /path/to/my/new/config - -Or, in parallel with the default index, by starting ``recoll`` without a -``-c`` option, and using the Preferences > External Index Dialog menu. - -Index case and diacritics sensitivity -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -As of RCL version 1.18 you have a choice of building an index with terms -stripped of character case and diacritics, or one with raw terms. For a -source term of ``Résumé``, the former will store ``resume``, the latter -``Résumé``. - -Each type of index allows performing searches insensitive to case and -diacritics: with a raw index, the user entry will be expanded to match -all case and diacritics variations present in the index. With a stripped -index, the search term will be stripped before searching. - -A raw index allows for another possibility which a stripped index cannot -offer: using case and diacritics to discriminate between terms, -returning different results when searching for ``US`` and ``us`` or -``resume`` and ``résumé``. Read the `section about search case and -diacritics sensitivity <#RCL.SEARCH.CASEDIAC>`__ for more details. - -The type of index to be created is controlled by the ``indexStripChars`` -configuration variable which can only be changed by editing the -configuration file. Any change implies an index reset (not automated by -RCL), and all indexes in a search must be set in the same way (again, -not checked by RCL). - -If the ``indexStripChars`` is not set, RCL 1.18 creates a stripped index -by default, for compatibility with previous versions. - -As a cost for added capability, a raw index will be slightly bigger than -a stripped one (around 10%). Also, searches will be more complex, so -probably slightly slower, and the feature is still young, so that a -certain amount of weirdness cannot be excluded. - -One of the most adverse consequence of using a raw index is that some -phrase and proximity searches may become impossible: because each term -needs to be expanded, and all combinations searched for, the -multiplicative expansion may become unmanageable. - -Indexing threads configuration -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The RCL indexing process ``recollindex`` can use multiple threads to -speed up indexing on multiprocessor systems. The work done to index -files is divided in several stages and some of the stages can be -executed by multiple threads. The stages are: - -1. File system walking: this is always performed by the main thread. - -2. File conversion and data extraction. - -3. Text processing (splitting, stemming, etc.). - -4. XAP index update. - -You can also read a `longer -document `__ -about the transformation of RCL indexing to multithreading. - -The threads configuration is controlled by two configuration file -parameters. - -``thrQSizes`` - This variable defines the job input queues configuration. There are - three possible queues for stages 2, 3 and 4, and this parameter - should give the queue depth for each stage (three integer values). - If a value of -1 is used for a given stage, no queue is used, and - the thread will go on performing the next stage. In practise, deep - queues have not been shown to increase performance. A value of 0 for - the first queue tells RCL to perform autoconfiguration (no need for - anything else in this case, thrTCounts is not used) - this is the - default configuration. - -``thrTCounts`` - This defines the number of threads used for each stage. If a value - of -1 is used for one of the queue depths, the corresponding thread - count is ignored. It makes no sense to use a value other than 1 for - the last stage because updating the XAP index is necessarily - single-threaded (and protected by a mutex). - - **Note** - - If the first value in ``thrQSizes`` is 0, ``thrTCounts`` is ignored. - -The following example would use three queues (of depth 2), and 4 threads -for converting source documents, 2 for processing their text, and one to -update the index. This was tested to be the best configuration on the -test system (quadri-processor with multiple disks). - -:: - - thrQSizes = 2 2 2 - thrTCounts = 4 2 1 - - -The following example would use a single queue, and the complete -processing for each document would be performed by a single thread -(several documents will still be processed in parallel in most cases). -The threads will use mutual exclusion when entering the index update -stage. In practise the performance would be close to the precedent case -in general, but worse in certain cases (e.g. a Zip archive would be -performed purely sequentially), so the previous approach is preferred. -YMMV... The 2 last values for thrTCounts are ignored. - -:: - - thrQSizes = 2 -1 -1 - thrTCounts = 6 1 1 - - -The following example would disable multithreading. Indexing will be -performed by a single thread. - -:: - - thrQSizes = -1 -1 -1 - - -The index configuration GUI -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Most parameters for a given index configuration can be set from a -``recoll`` GUI running on this configuration (either as default, or by -setting RECOLL\_CONFDIR or the ``-c`` option.) - -The interface is started from the Preferences > Index Configuration menu -entry. It is divided in four tabs, Global parameters, Local parameters, -Web history (which is explained in the next section) and Search -parameters. - -The Global parameters tab allows setting global variables, like the -lists of top directories, skipped paths, or stemming languages. - -The Local parameters tab allows setting variables that can be redefined -for subdirectories. This second tab has an initially empty list of -customisation directories, to which you can add. The variables are then -set for the currently selected directory (or at the top level if the -empty line is selected). - -The Search parameters section defines parameters which are used at query -time, but are global to an index and affect all search tools, not only -the GUI. - -The meaning for most entries in the interface is self-evident and -documented by a ``ToolTip`` popup on the text label. For more detail, -you will need to refer to the `configuration -section <#RCL.INSTALL.CONFIG>`__ of this guide. - -The configuration tool normally respects the comments and most of the -formatting inside the configuration file, so that it is quite possible -to use it on hand-edited files, which you might nevertheless want to -backup first... - -Indexing the WEB pages which you wisit. ---------------------------------------- - -With the help of a Firefox extension, RCL can index the Internet pages -that you visit. The extension has a long history: it was initially -designed for the Beagle indexer, then adapted to RCL and the Firefox XUL -API. A new version of the addon has been written to work with the -WebExtensions API, which is the only one supported after Firefox version -57. - -The extension works by copying visited WEB pages to an indexing queue -directory, which RCL then processes, indexing the data, storing it into -a local cache, then removing the file from the queue. - -Because the WebExtensions API introduces more constraints to what -extensions can do, the new version works with one more step: the files -are first created in the browser default downloads location (typically -``$HOME/Downloads`` ), then moved by a script in the old queue location. -The script is automatically executed by the RCL indexer versions 1.23.5 -and newer. It could conceivably be executed independantly to make the -new browser extension compatible with an older RCL version (the script -is named ``recoll-we-move-files.py``). - - **Note** - - For the WebExtensions-based version to work, it is necessary to set - the ``webdownloadsdir`` value in the configuration if it was changed - from the default ``$HOME/Downloads`` in the browser preferences. - -The visited WEB pages indexing feature can be enabled on the RCL side -from the GUI Index configuration panel, or by editing the configuration -file (set ``processwebqueue`` to 1). - -A current pointer to the extension can be found, along with up-to-date -instructions, on the `Recoll wiki <&FAQS;IndexWebHistory>`__. - -A copy of the indexed WEB pages is retained by Recoll in a local cache -(from which previews can be fetched). The cache size can be adjusted -from the Index configuration / Web history panel. Once the maximum size -is reached, old pages are purged - both from the cache and the index - -to make room for new ones, so you need to explicitly archive in some -other place the pages that you want to keep indefinitely. - -Extended attributes data ------------------------- - -User extended attributes are named pieces of information that most -modern file systems can attach to any file. - -RCL versions 1.19 and later process extended attributes as document -fields by default. For older versions, this has to be activated at build -time. - -A `freedesktop -standard `__ -defines a few special attributes, which are handled as such by RCL: - -mime\_type - If set, this overrides any other determination of the file MIME - type. - -charset - If set, this defines the file character set (mostly useful for plain - text files). - -By default, other attributes are handled as RCL fields. On Linux, the -``user`` prefix is removed from the name. This can be configured more -precisely inside the ```fields`` configuration -file <#RCL.INSTALL.CONFIG.FIELDS>`__. - -Importing external tags ------------------------ - -During indexing, it is possible to import metadata for each file by -executing commands. For example, this could extract user tag data for -the file and store it in a field for indexing. - -See the `section about the ``metadatacmds`` -field <#RCL.INSTALL.CONFIG.RECOLLCONF.METADATACMDS>`__ in the main -configuration chapter for a description of the configuration syntax. - -As an example, if you would want RCL to use tags managed by tmsu, you -would add the following to the configuration file: - -:: - - [/some/area/of/the/fs] - metadatacmds = ; tags = tmsu tags %f - - - **Note** - - Depending on the tmsu version, you may need/want to add options like - ``--database=/some/db``. - -You may want to restrict this processing to a subset of the directory -tree, because it may slow down indexing a bit -(``[some/area/of/the/fs]``). - -Note the initial semi-colon after the equal sign. - -In the example above, the output of ``tmsu`` is used to set a field -named ``tags``. The field name is arbitrary and could be ``tmsu`` or -``myfield`` just the same, but ``tags`` is an alias for the standard RCL -``keywords`` field, and the ``tmsu`` output will just augment its -contents. This will avoid the need to extend the `field -configuration <#RCL.PROGRAM.FIELDS>`__. - -Once re-indexing is performed (you'll need to force the file reindexing, -RCL will not detect the need by itself), you will be able to search from -the query language, through any of its aliases: -``tags:some/alternate/values`` or ``tags:all,these,values`` (the compact -field search syntax is supported for recoll 1.20 and later. For older -versions, you would need to repeat the ``tags:`` specifier for each -term, e.g. ``tags:some OR - tags:alternate``). - -You should be aware that tags changes will not be detected by the -indexer if the file itself did not change. One possible workaround would -be to update the file ``ctime`` when you modify the tags, which would be -consistent with how extended attributes function. A pair of ``chmod`` -commands could accomplish this, or a ``touch -a`` . Alternatively, just -couple the tag update with a ``recollindex -e -i - filename.`` - -The PDF input handler ---------------------- - -The PDF format is very important for scientific and technical -documentation, and document archival. It has extensive facilities for -storing metadata along with the document, and these facilities are -actually used in the real world. - -In consequence, the ``rclpdf.py`` PDF input handler has more complex -capabilities than most others, and it is also more configurable. -Specifically, ``rclpdf.py`` can automatically use tesseract to perform -OCR if the document text is empty, it can be configured to extract -specific metadata tags from an XMP packet, and to extract PDF -attachments. - -OCR with Tesseract -~~~~~~~~~~~~~~~~~~ - -If both tesseract and ``pdftoppm`` (generally from the poppler-utils -package) are installed, the PDF handler may attempt OCR on PDF files -with no text content. This is controlled by the -`pdfocr <#RCL.INSTALL.CONFIG.RECOLLCONF.PDFOCR>`__ configuration -variable, which is false by default because OCR is very slow. - -The choice of language is very important for successfull OCR. Recoll has -currently no way to determine this from the document itself. You can set -the language to use through the contents of a ``.ocrpdflang`` text file -in the same directory as the PDF document, or through the -RECOLL\_TESSERACT\_LANG environment variable, or through the contents of -an ``ocrpdf`` text file inside the configuration directory. If none of -the above are used, RCL will try to guess the language from the NLS -environment. - -XMP fields extraction -~~~~~~~~~~~~~~~~~~~~~ - -The ``rclpdf.py`` script in RCL version 1.23.2 and later can extract XMP -metadata fields by executing the ``pdfinfo`` command (usually found with -poppler-utils). This is controlled by the -`pdfextrameta <#RCL.INSTALL.CONFIG.RECOLLCONF.PDFEXTRAMETA>`__ -configuration variable, which specifies which tags to extract and, -possibly, how to rename them. - -The `pdfextrametafix <#RCL.INSTALL.CONFIG.RECOLLCONF.PDFEXTRAMETAFIX>`__ -variable can be used to designate a file with Python code to edit the -metadata fields (available for RCL 1.23.3 and later. 1.23.2 has -equivalent code inside the handler script). Example: - -:: - - import sys - import re - - class MetaFixer(object): - def __init__(self): - pass - - def metafix(self, nm, txt): - if nm == 'bibtex:pages': - txt = re.sub(r'--', '-', txt) - elif nm == 'someothername': - # do something else - pass - elif nm == 'stillanother': - # etc. - pass - - return txt - def wrapup(self, metaheaders): - pass - - -If the 'metafix()' method is defined, it is called for each metadata -field. A new MetaFixer object is created for each PDF document (so the -object can keep state for, for example, eliminating duplicate values). -If the 'wrapup()' method is defined, it is called at the end of XMP -fields processing with the whole metadata as parameter, as an array of -'(nm, val)' pairs, allowing an alternate approach for editing or -adding/deleting fields. - -PDF attachment indexing -~~~~~~~~~~~~~~~~~~~~~~~ - -If pdftk is installed, and if the the -`pdfattach <#RCL.INSTALL.CONFIG.RECOLLCONF.PDFATTACH>`__ configuration -variable is set, the PDF input handler will try to extract PDF -attachements for indexing as sub-documents of the PDF file. This is -disabled by default, because it slows down PDF indexing a bit even if -not one attachment is ever found (PDF attachments are uncommon in my -experience). - -Periodic indexing ------------------ - -Running indexing -~~~~~~~~~~~~~~~~ - -Indexing is always performed by the ``recollindex`` program, which can -be started either from the command line or from the File menu in the -``recoll`` GUI program. When started from the GUI, the indexing will run -on the same configuration ``recoll`` was started on. When started from -the command line, ``recollindex`` will use the RECOLL\_CONFDIR variable -or accept a ``-c`` confdir option to specify a non-default configuration -directory. - -If the ``recoll`` program finds no index when it starts, it will -automatically start indexing (except if canceled). - -The ``recollindex`` indexing process can be interrupted by sending an -interrupt (Ctrl-C, SIGINT) or terminate (SIGTERM) signal. Some time may -elapse before the process exits, because it needs to properly flush and -close the index. This can also be done from the ``recoll`` GUI File > -Stop Indexing menu entry. - -After such an interruption, the index will be somewhat inconsistent -because some operations which are normally performed at the end of the -indexing pass will have been skipped (for example, the stemming and -spelling databases will be inexistant or out of date). You just need to -restart indexing at a later time to restore consistency. The indexing -will restart at the interruption point (the full file tree will be -traversed, but files that were indexed up to the interruption and for -which the index is still up to date will not need to be reindexed). - -``recollindex`` has a number of other options which are described in its -man page. Only a few will be described here. - -Option ``-z`` will reset the index when starting. This is almost the -same as destroying the index files (the nuance is that the XAP format -version will not be changed). - -Option ``-Z`` will force the update of all documents without resetting -the index first. This will not have the "clean start" aspect of ``-z``, -but the advantage is that the index will remain available for querying -while it is rebuilt, which can be a significant advantage if it is very -big (some installations need days for a full index rebuild). - -Option ``-k`` will force retrying files which previously failed to be -indexed, for example because of a missing helper program. - -Of special interest also, maybe, are the ``-i`` and ``-f`` options. -``-i`` allows indexing an explicit list of files (given as command line -parameters or read on ``stdin``). ``-f`` tells ``recollindex`` to ignore -file selection parameters from the configuration. Together, these -options allow building a custom file selection process for some area of -the file system, by adding the top directory to the ``skippedPaths`` -list and using an appropriate file selection method to build the file -list to be fed to ``recollindex`` ``-if``. Trivial example: - -:: - - find . -name indexable.txt -print | recollindex -if - - -``recollindex`` ``-i`` will not descend into subdirectories specified as -parameters, but just add them as index entries. It is up to the external -file selection method to build the complete file list. - -Using ``cron`` to automate indexing -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The most common way to set up indexing is to have a cron task execute it -every night. For example the following ``crontab`` entry would do it -every day at 3:30AM (supposing ``recollindex`` is in your PATH): - -:: - - 30 3 * * * recollindex > /some/tmp/dir/recolltrace 2>&1 - - -Or, using ``anacron``: - -:: - - 1 15 su mylogin -c "recollindex recollindex > /tmp/rcltraceme 2>&1" - - -As of version 1.17 the RCL GUI has dialogs to manage ``crontab`` entries -for ``recollindex``. You can reach them from the Preferences > Indexing -Schedule menu. They only work with the good old ``cron``, and do not -give access to all features of ``cron`` scheduling. - -The usual command to edit your ``crontab`` is ``crontab`` ``-e`` (which -will usually start the ``vi`` editor to edit the file). You may have -more sophisticated tools available on your system. - -Please be aware that there may be differences between your usual -interactive command line environment and the one seen by crontab -commands. Especially the PATH variable may be of concern. Please check -the crontab manual pages about possible issues. - -Real time indexing ------------------- - -Real time monitoring/indexing is performed by starting the -``recollindex`` ``-m`` command. With this option, ``recollindex`` will -detach from the terminal and become a daemon, permanently monitoring -file changes and updating the index. - -While it is convenient that data is indexed in real time, repeated -indexing can generate a significant load on the system when files such -as email folders change. Also, monitoring large file trees by itself -significantly taxes system resources. You probably do not want to enable -it if your system is short on resources. Periodic indexing is adequate -in most cases. - -As of RCL 1.24, you can set the -`monitordirs <#RCL.INSTALL.CONFIG.RECOLLCONF.MONITORDIRS>`__ -configuration variable to specify that only a subset of your indexed -files will be monitored for instant indexing. In this situation, an -incremental pass on the full tree can be triggered by either restarting -the indexer, or just running ``recollindex``, which will notify the -running process. The ``recoll`` GUI also has a menu entry for this. - -Real time indexing: automatic daemon start -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Under KDE, Gnome and some other desktop environments, the daemon can -automatically started when you log in, by creating a desktop file inside -the ``~/.config/autostart`` directory. This can be done for you by the -RCL GUI. Use the Preferences->Indexing Schedule menu. - -With older X11 setups, starting the daemon is normally performed as part -of the user session script. - -The ``rclmon.sh`` script can be used to easily start and stop the -daemon. It can be found in the ``examples`` directory (typically -``/usr/local/[share/]recoll/examples``). - -For example, my out of fashion xdm-based session has a ``.xsession`` -script with the following lines at the end: - -:: - - recollconf=$HOME/.recoll-home - recolldata=/usr/local/share/recoll - RECOLL_CONFDIR=$recollconf $recolldata/examples/rclmon.sh start - - fvwm - - - -The indexing daemon gets started, then the window manager, for which the -session waits. - -By default the indexing daemon will monitor the state of the X11 -session, and exit when it finishes, it is not necessary to kill it -explicitly. (The X11 server monitoring can be disabled with option -``-x`` to ``recollindex``). - -If you use the daemon completely out of an X11 session, you need to add -option ``-x`` to disable X11 session monitoring (else the daemon will -not start). - -Real time indexing: miscellaneous details -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -By default, the messages from the indexing daemon will be sent to the -same file as those from the interactive commands (``logfilename``). You -may want to change this by setting the ``daemlogfilename`` and -``daemloglevel`` configuration parameters. Also the log file will only -be truncated when the daemon starts. If the daemon runs permanently, the -log file may grow quite big, depending on the log level. - -When building RCL, the real time indexing support can be customised -during package `configuration <#RCL.INSTALL.BUILDING>`__ with the -``--with[out]-fam`` or ``--with[out]-inotify`` options. The default is -currently to include inotify monitoring on systems that support it, and, -as of RCL 1.17, gamin support on FreeBSD. - - **Note** - - On Linux systems, monitoring a big tree may need increasing the - resources available to inotify, which are normally defined in - ``/etc/sysctl.conf``. - - :: - - ### inotify - # - # cat /proc/sys/fs/inotify/max_queued_events - 16384 - # cat /proc/sys/fs/inotify/max_user_instances - 128 - # cat /proc/sys/fs/inotify/max_user_watches - 16384 - # - # -- Change to: - # - fs.inotify.max_queued_events=32768 - fs.inotify.max_user_instances=256 - fs.inotify.max_user_watches=32768 - - - Especially, you will need to trim your tree or adjust the - ``max_user_watches`` value if indexing exits with a message about - errno ``ENOSPC`` (28) from ``inotify_add_watch``. - - **Note** - - When using the real time monitor, it may happen that some files need - to be indexed, but change so often that they impose an excessive - load for the system. - - RCL provides a configuration option to specify the minimum time - before which a file, specified by a wildcard pattern, cannot be - reindexed. See the ``mondelaypatterns`` parameter in the - `configuration section <#RCL.INSTALL.CONFIG.RECOLLCONF.MISC>`__. - -Searching -========= - -Searching with the Qt graphical user interface ----------------------------------------------- - -The ``recoll`` program provides the main user interface for searching. -It is based on the Qt library. - -``recoll`` has two search modes: - -- Simple search (the default, on the main screen) has a single entry - field where you can enter multiple words. - -- Advanced search (a panel accessed through the Tools menu or the - toolbox bar icon) has multiple entry fields, which you may use to - build a logical condition, with additional filtering on file type, - location in the file system, modification date, and size. - -In most cases, you can enter the terms as you think them, even if they -contain embedded punctuation or other non-textual characters. For -example, RCL can handle things like email addresses, or arbitrary cut -and paste from another text window, punctation and all. - -The main case where you should enter text differently from how it is -printed is for east-asian languages (Chinese, Japanese, Korean). Words -composed of single or multiple characters should be entered separated by -white space in this case (they would typically be printed without white -space). - -Some searches can be quite complex, and you may want to re-use them -later, perhaps with some tweaking. RCL versions 1.21 and later can save -and restore searches, using XML files. See `Saving and restoring -queries <#RCL.SEARCH.SAVING>`__. - -Simple search -~~~~~~~~~~~~~ - -Start the ``recoll`` program. - -Possibly choose a search mode: Any term, All terms, File name or Query -language. - -Enter search term(s) in the text field at the top of the window. - -Click the Search button or hit the Enter key to start the search. - -The initial default search mode is Query language. Without special -directives, this will look for documents containing all of the search -terms (the ones with more terms will get better scores), just like the -All terms mode. Any term will search for documents where at least one of -the terms appear. - -The Query Language features are described in `a separate -section <#RCL.SEARCH.LANG>`__. - -All search modes allow terms to be expanded with wildcards characters -(``*``, ``?``, ``[]``). See the `section about -wildcards <#RCL.SEARCH.WILDCARDS>`__ for more details. - -The File name search mode will specifically look for file names. The -point of having a separate file name search is that wild card expansion -can be performed more efficiently on a small subset of the index -(allowing wild cards on the left of terms without excessive penality). -Things to know: - -- White space in the entry should match white space in the file name, - and is not treated specially. - -- The search is insensitive to character case and accents, - independantly of the type of index. - -- An entry without any wild card character and not capitalized will be - prepended and appended with '\*' (ie: etc -> \*etc\*, but Etc -> - etc). - -- If you have a big index (many files), excessively generic fragments - may result in inefficient searches. - -In all modes except File name, you can search for exact phrases -(adjacent words in a given order) by enclosing the input inside double -quotes. Ex: ``"virtual - reality"``. - -When using a stripped index (the default), character case has no -influence on search, except that you can disable stem expansion for any -term by capitalizing it. Ie: a search for ``floor`` will also normally -look for ``flooring``, ``floored``, etc., but a search for ``Floor`` -will only look for ``floor``, in any character case. Stemming can also -be disabled globally in the preferences. When using a raw index, `the -rules are a bit more complicated <#RCL.SEARCH.CASEDIAC>`__. - -RCL remembers the last few searches that you performed. You can directly -access the search history by clicking the clock button on the right of -the search entry, while the latter is empty. Otherwise, the history is -used for entry completion (see next). Only the search texts are -remembered, not the mode (all/any/file name). - -While text is entered in the search area, ``recoll`` will display -possible completions, filtered from the history and the index search -terms. This can be disabled with a GUI Preferences option. - -Double-clicking on a word in the result list or a preview window will -insert it into the simple search entry field. - -You can cut and paste any text into an All terms or Any term search -field, punctuation, newlines and all - except for wildcard characters -(single ``?`` characters are ok). RCL will process it and produce a -meaningful search. This is what most differentiates this mode from the -Query Language mode, where you have to care about the syntax. - -You can use the `Tools > Advanced search <#RCL.SEARCH.GUI.COMPLEX>`__ -dialog for more complex searches. - -The default result list -~~~~~~~~~~~~~~~~~~~~~~~ - -After starting a search, a list of results will instantly be displayed -in the main list window. - -By default, the document list is presented in order of relevance (how -well the system estimates that the document matches the query). You can -sort the result by ascending or descending date by using the vertical -arrows in the toolbar. - -Clicking on the ``Preview`` link for an entry will open an internal -preview window for the document. Further ``Preview`` clicks for the same -search will open tabs in the existing preview window. You can use -Shift+Click to force the creation of another preview window, which may -be useful to view the documents side by side. (You can also browse -successive results in a single preview window by typing -Shift+ArrowUp/Down in the window). - -Clicking the ``Open`` link will start an external viewer for the -document. By default, RCL lets the desktop choose the appropriate -application for most document types (there is a short list of -exceptions, see further). If you prefer to completely customize the -choice of applications, you can uncheck the Use desktop preferences -option in the GUI preferences dialog, and click the Choose editor -applications button to adjust the predefined RCL choices. The tool -accepts multiple selections of MIME types (e.g. to set up the editor for -the dozens of office file types). - -Even when Use desktop preferences is checked, there is a small list of -exceptions, for MIME types where the RCL choice should override the -desktop one. These are applications which are well integrated with RCL, -especially evince for viewing PDF and Postscript files because of its -support for opening the document at a specific page and passing a search -string as an argument. Of course, you can edit the list (in the GUI -preferences) if you would prefer to lose the functionality and use the -standard desktop tool. - -You may also change the choice of applications by editing the -```mimeview`` <#RCL.INSTALL.CONFIG.MIMEVIEW>`__ configuration file if -you find this more convenient. - -Each result entry also has a right-click menu with an Open With entry. -This lets you choose an application from the list of those which -registered with the desktop for the document MIME type. - -The ``Preview`` and ``Open`` edit links may not be present for all -entries, meaning that RCL has no configured way to preview a given file -type (which was indexed by name only), or no configured external editor -for the file type. This can sometimes be adjusted simply by tweaking the -```mimemap`` <#RCL.INSTALL.CONFIG.MIMEMAP>`__ and -```mimeview`` <#RCL.INSTALL.CONFIG.MIMEVIEW>`__ configuration files (the -latter can be modified with the user preferences dialog). - -The format of the result list entries is entirely configurable by using -the preference dialog to `edit an HTML -fragment <#RCL.SEARCH.GUI.CUSTOM.RESLIST>`__. - -You can click on the ``Query details`` link at the top of the results -page to see the query actually performed, after stem expansion and other -processing. - -Double-clicking on any word inside the result list or a preview window -will insert it into the simple search text. - -The result list is divided into pages (the size of which you can change -in the preferences). Use the arrow buttons in the toolbar or the links -at the bottom of the page to browse the results. - -No results: the spelling suggestions -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -When a search yields no result, and if the aspell dictionary is -configured, RCL will try to check for misspellings among the query -terms, and will propose lists of replacements. Clicking on one of the -suggestions will replace the word and restart the search. You can hold -any of the modifier keys (Ctrl, Shift, etc.) while clicking if you would -rather stay on the suggestion screen because several terms need -replacement. - -The result list right-click menu -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Apart from the preview and edit links, you can display a pop-up menu by -right-clicking over a paragraph in the result list. This menu has the -following entries: - -- Preview - -- Open - -- Open With - -- Run Script - -- Copy File Name - -- Copy Url - -- Save to File - -- Find similar - -- Preview Parent document - -- Open Parent document - -- Open Snippets Window - -The Preview and Open entries do the same thing as the corresponding -links. - -Open With lets you open the document with one of the applications -claiming to be able to handle its MIME type (the information comes from -the ``.desktop`` files in ``/usr/share/applications``). - -Run Script allows starting an arbitrary command on the result file. It -will only appear for results which are top-level files. See -`further <#RCL.SEARCH.GUI.RUNSCRIPT>`__ for a more detailed description. - -The Copy File Name and Copy Url copy the relevant data to the clipboard, -for later pasting. - -Save to File allows saving the contents of a result document to a chosen -file. This entry will only appear if the document does not correspond to -an existing file, but is a subdocument inside such a file (ie: an email -attachment). It is especially useful to extract attachments with no -associated editor. - -The Open/Preview Parent document entries allow working with the higher -level document (e.g. the email message an attachment comes from). RCL is -sometimes not totally accurate as to what it can or can't do in this -area. For example the Parent entry will also appear for an email which -is part of an mbox folder file, but you can't actually visualize the -mbox (there will be an error dialog if you try). - -If the document is a top-level file, Open Parent will start the default -file manager on the enclosing filesystem directory. - -The Find similar entry will select a number of relevant term from the -current document and enter them into the simple search field. You can -then start a simple search, with a good chance of finding documents -related to the current result. I can't remember a single instance where -this function was actually useful to me... - -The Open Snippets Window entry will only appear for documents which -support page breaks (typically PDF, Postscript, DVI). The snippets -window lists extracts from the document, taken around search terms -occurrences, along with the corresponding page number, as links which -can be used to start the native viewer on the appropriate page. If the -viewer supports it, its search function will also be primed with one of -the search terms. - -The result table -~~~~~~~~~~~~~~~~ - -In RCL 1.15 and newer, the results can be displayed in spreadsheet-like -fashion. You can switch to this presentation by clicking the table-like -icon in the toolbar (this is a toggle, click again to restore the list). - -Clicking on the column headers will allow sorting by the values in the -column. You can click again to invert the order, and use the header -right-click menu to reset sorting to the default relevance order (you -can also use the sort-by-date arrows to do this). - -Both the list and the table display the same underlying results. The -sort order set from the table is still active if you switch back to the -list mode. You can click twice on a date sort arrow to reset it from -there. - -The header right-click menu allows adding or deleting columns. The -columns can be resized, and their order can be changed (by dragging). -All the changes are recorded when you quit ``recoll`` - -Hovering over a table row will update the detail area at the bottom of -the window with the corresponding values. You can click the row to -freeze the display. The bottom area is equivalent to a result list -paragraph, with links for starting a preview or a native application, -and an equivalent right-click menu. Typing Esc (the Escape key) will -unfreeze the display. - -Running arbitrary commands on result files (1.20 and later) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Apart from the Open and Open With operations, which allow starting an -application on a result document (or a temporary copy), based on its -MIME type, it is also possible to run arbitrary commands on results -which are top-level files, using the Run Script entry in the results -pop-up menu. - -The commands which will appear in the Run Script submenu must be defined -by ``.desktop`` files inside the ``scripts`` subdirectory of the current -configuration directory. - -Here follows an example of a ``.desktop`` file, which could be named for -example, ``~/.recoll/scripts/myscript.desktop`` (the exact file name -inside the directory is irrelevant): - -:: - - [Desktop Entry] - Type=Application - Name=MyFirstScript - Exec=/home/me/bin/tryscript %F - MimeType=*/* - - -The ``Name`` attribute defines the label which will appear inside the -Run Script menu. The ``Exec`` attribute defines the program to be run, -which does not need to actually be a script, of course. The ``MimeType`` -attribute is not used, but needs to exist. - -The commands defined this way can also be used from links inside the -`result paragraph <#RCL.SEARCH.GUI.CUSTOM.RESLIST.PARA>`__. - -As an example, it might make sense to write a script which would move -the document to the trash and purge it from the RCL index. - -Displaying thumbnails -~~~~~~~~~~~~~~~~~~~~~ - -The default format for the result list entries and the detail area of -the result table display an icon for each result document. The icon is -either a generic one determined from the MIME type, or a thumbnail of -the document appearance. Thumbnails are only displayed if found in the -standard freedesktop location, where they would typically have been -created by a file manager. - -Recoll has no capability to create thumbnails. A relatively simple trick -is to use the Open parent document/folder entry in the result list popup -menu. This should open a file manager window on the containing -directory, which should in turn create the thumbnails (depending on your -settings). Restarting the search should then display the thumbnails. - -There are also `some pointers about thumbnail -generation <&FAQS;ResultsThumbnails.wiki>`__ on the RCL wiki. - -The preview window -~~~~~~~~~~~~~~~~~~ - -The preview window opens when you first click a ``Preview`` link inside -the result list. - -Subsequent preview requests for a given search open new tabs in the -existing window (except if you hold the Shift key while clicking which -will open a new window for side by side viewing). - -Starting another search and requesting a preview will create a new -preview window. The old one stays open until you close it. - -You can close a preview tab by typing Ctrl-W (Ctrl + W) in the window. -Closing the last tab for a window will also close the window. - -Of course you can also close a preview window by using the window -manager button in the top of the frame. - -You can display successive or previous documents from the result list -inside a preview tab by typing Shift+Down or Shift+Up (Down and Up are -the arrow keys). - -A right-click menu in the text area allows switching between displaying -the main text or the contents of fields associated to the document (ie: -author, abtract, etc.). This is especially useful in cases where the -term match did not occur in the main text but in one of the fields. In -the case of images, you can switch between three displays: the image -itself, the image metadata as extracted by ``exiftool`` and the fields, -which is the metadata stored in the index. - -You can print the current preview window contents by typing Ctrl-P (Ctrl -+ P) in the window text. - -Searching inside the preview -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The preview window has an internal search capability, mostly controlled -by the panel at the bottom of the window, which works in two modes: as a -classical editor incremental search, where we look for the text entered -in the entry zone, or as a way to walk the matches between the document -and the RCL query that found it. - -Incremental text search - The preview tabs have an internal incremental search function. You - initiate the search either by typing a / (slash) or CTL-F inside the - text area or by clicking into the Search for: text field and - entering the search string. You can then use the Next and Previous - buttons to find the next/previous occurrence. You can also type F3 - inside the text area to get to the next occurrence. - - If you have a search string entered and you use Ctrl-Up/Ctrl-Down to - browse the results, the search is initiated for each successive - document. If the string is found, the cursor will be positioned at - the first occurrence of the search string. - -Walking the match lists - If the entry area is empty when you click the Next or Previous - buttons, the editor will be scrolled to show the next match to any - search term (the next highlighted zone). If you select a search - group from the dropdown list and click Next or Previous, the match - list for this group will be walked. This is not the same as a text - search, because the occurences will include non-exact matches (as - caused by stemming or wildcards). The search will revert to the text - mode as soon as you edit the entry area. - -The Query Fragments window -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Selecting the Tools > Query Fragments menu entry will open a window with -radio- and check-buttons which can be used to activate query language -fragments for filtering the current query. This can be useful if you -have frequent reusable selectors, for example, filtering on alternate -directories, or searching just one category of files, not covered by the -standard category selectors. - -The contents of the window are entirely customizable, and defined by the -contents of the ``fragbuts.xml`` file inside the configuration -directory. The sample file distributed with RCL (which you should be -able to find under ``/usr/share/recoll/examples/fragbuts.xml``), -contains an example which filters the results from the WEB history. - -Here follows an example: - -:: - - - - - - - - - - - - - - - -rclbes:BGL - - - - - rclbes:BGL - - - - - - - - - date:2010-01-01/2010-12-31 - - - - - dir:/my/great/directory - - - - - - -Each ``radiobuttons`` or ``buttons`` section defines a line of -checkbuttons or radiobuttons inside the window. Any number of buttons -can be selected, but the radiobuttons in a line are exclusive. - -Each ``fragbut`` section defines the label for a button, and the Query -Language fragment which will be added (as an AND filter) before -performing the query if the button is active. - -This feature is new in RCL 1.20, and will probably be refined depending -on user feedback. - -Complex/advanced search -~~~~~~~~~~~~~~~~~~~~~~~ - -The advanced search dialog helps you build more complex queries without -memorizing the search language constructs. It can be opened through the -Tools menu or through the main toolbar. - -RCL keeps a history of searches. See `Advanced search -history <#RCL.SEARCH.GUI.COMPLEX.HISTORY>`__. - -The dialog has two tabs: - -1. The first tab lets you specify terms to search for, and permits - specifying multiple clauses which are combined to build the search. - -2. The second tab lets filter the results according to file size, date - of modification, MIME type, or location. - -Click on the Start Search button in the advanced search dialog, or type -Enter in any text field to start the search. The button in the main -window always performs a simple search. - -Click on the ``Show query details`` link at the top of the result page -to see the query expansion. - -Avanced search: the "find" tab -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -This part of the dialog lets you constructc a query by combining -multiple clauses of different types. Each entry field is configurable -for the following modes: - -- All terms. - -- Any term. - -- None of the terms. - -- Phrase (exact terms in order within an adjustable window). - -- Proximity (terms in any order within an adjustable window). - -- Filename search. - -Additional entry fields can be created by clicking the Add clause -button. - -When searching, the non-empty clauses will be combined either with an -AND or an OR conjunction, depending on the choice made on the left (All -clauses or Any clause). - -Entries of all types except "Phrase" and "Near" accept a mix of single -words and phrases enclosed in double quotes. Stemming and wildcard -expansion will be performed as for simple search. - -**Phrases and Proximity searches.** - -These two clauses work in similar ways, with the difference that -proximity searches do not impose an order on the words. In both cases, -an adjustable number (slack) of non-matched words may be accepted -between the searched ones (use the counter on the left to adjust this -count). For phrases, the default count is zero (exact match). For -proximity it is ten (meaning that two search terms, would be matched if -found within a window of twelve words). Examples: a phrase search for -``quick - fox`` with a slack of 0 will match ``quick - fox`` but not ``quick brown fox``. With a slack of 1 it will -match the latter, but not ``fox - quick``. A proximity search for ``quick - fox`` with the default slack will match the latter, and also -``a fox is a cunning and quick - animal``. - -Avanced search: the "filter" tab -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -This part of the dialog has several sections which allow filtering the -results of a search according to a number of criteria - -- The first section allows filtering by dates of last modification. You - can specify both a minimum and a maximum date. The initial values are - set according to the oldest and newest documents found in the index. - -- The next section allows filtering the results by file size. There are - two entries for minimum and maximum size. Enter decimal numbers. You - can use suffix multipliers: ``k/K``, ``m/M``, ``g/G``, ``t/T`` for - 1E3, 1E6, 1E9, 1E12 respectively. - -- The next section allows filtering the results by their MIME types, or - MIME categories (ie: media/text/message/etc.). - - You can transfer the types between two boxes, to define which will be - included or excluded by the search. - - The state of the file type selection can be saved as the default (the - file type filter will not be activated at program start-up, but the - lists will be in the restored state). - -- The bottom section allows restricting the search results to a - sub-tree of the indexed area. You can use the Invert checkbox to - search for files not in the sub-tree instead. If you use directory - filtering often and on big subsets of the file system, you may think - of setting up multiple indexes instead, as the performance may be - better. - - You can use relative/partial paths for filtering. Ie, entering - ``dirA/dirB`` would match either ``/dir1/dirA/dirB/myfile1`` or - ``/dir2/dirA/dirB/someother/myfile2``. - -Avanced search history -^^^^^^^^^^^^^^^^^^^^^^ - -The advanced search tool memorizes the last 100 searches performed. You -can walk the saved searches by using the up and down arrow keys while -the keyboard focus belongs to the advanced search dialog. - -The complex search history can be erased, along with the one for simple -search, by selecting the File > Erase Search History menu entry. - -The term explorer tool -~~~~~~~~~~~~~~~~~~~~~~ - -RCL automatically manages the expansion of search terms to their -derivatives (ie: plural/singular, verb inflections). But there are other -cases where the exact search term is not known. For example, you may not -remember the exact spelling, or only know the beginning of the name. - -The search will only propose replacement terms with spelling variations -when no matching document were found. In some cases, both proper -spellings and mispellings are present in the index, and it may be -interesting to look for them explicitely. - -The term explorer tool (started from the toolbar icon or from the Term -explorer entry of the Tools menu) can be used to search the full index -terms list. It has three modes of operations: - -Wildcard - In this mode of operation, you can enter a search string with - shell-like wildcards (\*, ?, []). ie: xapi\* would display all index - terms beginning with xapi. (More about wildcards - `here <#RCL.SEARCH.WILDCARDS>`__). - -Regular expression - This mode will accept a regular expression as input. Example: - word[0-9]+. The expression is implicitely anchored at the beginning. - Ie: press will match pression but not expression. You can use - .\*press to match the latter, but be aware that this will cause a - full index term list scan, which can be quite long. - -Stem expansion - This mode will perform the usual stem expansion normally done as - part user input processing. As such it is probably mostly useful to - demonstrate the process. - -Spelling/Phonetic - In this mode, you enter the term as you think it is spelled, and RCL - will do its best to find index terms that sound like your entry. - This mode uses the Aspell spelling application, which must be - installed on your system for things to work (if your documents - contain non-ascii characters, RCL needs an aspell version newer than - 0.60 for UTF-8 support). The language which is used to build the - dictionary out of the index terms (which is done at the end of an - indexing pass) is the one defined by your NLS environment. Weird - things will probably happen if languages are mixed up. - -Note that in cases where RCL does not know the beginning of the string -to search for (ie a wildcard expression like \*coll), the expansion can -take quite a long time because the full index term list will have to be -processed. The expansion is currently limited at 10000 results for -wildcards and regular expressions. It is possible to change the limit in -the configuration file. - -Double-clicking on a term in the result list will insert it into the -simple search entry field. You can also cut/paste between the result -list and any entry field (the end of lines will be taken care of). - -Multiple indexes -~~~~~~~~~~~~~~~~ - -See the `section describing the use of multiple -indexes <#RCL.INDEXING.CONFIG.MULTIPLE>`__ for generalities. Only the -aspects concerning the ``recoll`` GUI are described here. - -A ``recoll`` program instance is always associated with a specific -index, which is the one to be updated when requested from the File menu, -but it can use any number of RCL indexes for searching. The external -indexes can be selected through the external indexes tab in the -preferences dialog. - -Index selection is performed in two phases. A set of all usable indexes -must first be defined, and then the subset of indexes to be used for -searching. These parameters are retained across program executions -(there are kept separately for each RCL configuration). The set of all -indexes is usually quite stable, while the active ones might typically -be adjusted quite frequently. - -The main index (defined by RECOLL\_CONFDIR) is always active. If this is -undesirable, you can set up your base configuration to index an empty -directory. - -When adding a new index to the set, you can select either a RCL -configuration directory, or directly a XAP index directory. In the first -case, the XAP index directory will be obtained from the selected -configuration. - -As building the set of all indexes can be a little tedious when done -through the user interface, you can use the RECOLL\_EXTRA\_DBS -environment variable to provide an initial set. This might typically be -set up by a system administrator so that every user does not have to do -it. The variable should define a colon-separated list of index -directories, ie: - -:: - - export RECOLL_EXTRA_DBS=/some/place/xapiandb:/some/other/db - -Another environment variable, RECOLL\_ACTIVE\_EXTRA\_DBS allows adding -to the active list of indexes. This variable was suggested and -implemented by a RCL user. It is mostly useful if you use scripts to -mount external volumes with RCL indexes. By using RECOLL\_EXTRA\_DBS and -RECOLL\_ACTIVE\_EXTRA\_DBS, you can add and activate the index for the -mounted volume when starting ``recoll``. - -RECOLL\_ACTIVE\_EXTRA\_DBS is available for RCL versions 1.17.2 and -later. A change was made in the same update so that ``recoll`` will -automatically deactivate unreachable indexes when starting up. - -Document history -~~~~~~~~~~~~~~~~ - -Documents that you actually view (with the internal preview or an -external tool) are entered into the document history, which is -remembered. - -You can display the history list by using the Tools/Doc History menu -entry. - -You can erase the document history by using the Erase document history -entry in the File menu. - -Sorting search results and collapsing duplicates -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The documents in a result list are normally sorted in order of -relevance. It is possible to specify a different sort order, either by -using the vertical arrows in the GUI toolbox to sort by date, or -switching to the result table display and clicking on any header. The -sort order chosen inside the result table remains active if you switch -back to the result list, until you click one of the vertical arrows, -until both are unchecked (you are back to sort by relevance). - -Sort parameters are remembered between program invocations, but result -sorting is normally always inactive when the program starts. It is -possible to keep the sorting activation state between program -invocations by checking the Remember sort activation state option in the -preferences. - -It is also possible to hide duplicate entries inside the result list -(documents with the exact same contents as the displayed one). The test -of identity is based on an MD5 hash of the document container, not only -of the text contents (so that ie, a text document with an image added -will not be a duplicate of the text only). Duplicates hiding is -controlled by an entry in the GUI configuration dialog, and is off by -default. - -As of release 1.19, when a result document does have undisplayed -duplicates, a ``Dups`` link will be shown with the result list entry. -Clicking the link will display the paths (URLs + ipaths) for the -duplicate entries. - -Search tips, shortcuts -~~~~~~~~~~~~~~~~~~~~~~ - -Terms and search expansion -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -**Term completion.** - -Typing Esc Space in the simple search entry field while entering a word -will either complete the current word if its beginning matches a unique -term in the index, or open a window to propose a list of completions. - -**Picking up new terms from result or preview text.** - -Double-clicking on a word in the result list or in a preview window will -copy it to the simple search entry field. - -**Wildcards.** - -Wildcards can be used inside search terms in all forms of searches. -`More about wildcards <#RCL.SEARCH.WILDCARDS>`__. - -**Automatic suffixes.** - -Words like ``odt`` or ``ods`` can be automatically turned into query -language ``ext:xxx`` clauses. This can be enabled in the Search -preferences panel in the GUI. - -**Disabling stem expansion.** - -Entering a capitalized word in any search field will prevent stem -expansion (no search for ``gardening`` if you enter ``Garden`` instead -of ``garden``). This is the only case where character case should make a -difference for a RCL search. You can also disable stem expansion or -change the stemming language in the preferences. - -**Finding related documents.** - -Selecting the Find similar documents entry in the result list paragraph -right-click menu will select a set of "interesting" terms from the -current result, and insert them into the simple search entry field. You -can then possibly edit the list and start a search to find documents -which may be apparented to the current result. - -**File names.** - -File names are added as terms during indexing, and you can specify them -as ordinary terms in normal search fields (RCL used to index all -directories in the file path as terms. This has been abandoned as it did -not seem really useful). Alternatively, you can use the specific file -name search which will *only* look for file names, and may be faster -than the generic search especially when using wildcards. - -Working with phrases and proximity -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -**Phrases and Proximity searches.** - -A phrase can be looked for by enclosing it in double quotes. Example: -``"user manual"`` will look only for occurrences of ``user`` immediately -followed by ``manual``. You can use the This phrase field of the -advanced search dialog to the same effect. Phrases can be entered along -simple terms in all simple or advanced search entry fields (except This -exact phrase). - -**AutoPhrases.** - -This option can be set in the preferences dialog. If it is set, a phrase -will be automatically built and added to simple searches when looking -for ``Any terms``. This will not change radically the results, but will -give a relevance boost to the results where the search terms appear as a -phrase. Ie: searching for ``virtual reality`` will still find all -documents where either ``virtual`` or ``reality`` or both appear, but -those which contain ``virtual - reality`` should appear sooner in the list. - -Phrase searches can strongly slow down a query if most of the terms in -the phrase are common. This is why the ``autophrase`` option is off by -default for RCL versions before 1.17. As of version 1.17, ``autophrase`` -is on by default, but very common terms will be removed from the -constructed phrase. The removal threshold can be adjusted from the -search preferences. - -**Phrases and abbreviations.** - -As of RCL version 1.17, dotted abbreviations like ``I.B.M.`` are also -automatically indexed as a word without the dots: ``IBM``. Searching for -the word inside a phrase (ie: ``"the IBM company"``) will only match the -dotted abrreviation if you increase the phrase slack (using the advanced -search panel control, or the ``o`` query language modifier). Literal -occurences of the word will be matched normally. - -Others -^^^^^^ - -**Using fields.** - -You can use the `query language <#RCL.SEARCH.LANG>`__ and field -specifications to only search certain parts of documents. This can be -especially helpful with email, for example only searching emails from a -specific originator: ``search tips from:helpfulgui`` - -**Ajusting the result table columns.** - -When displaying results in table mode, you can use a right click on the -table headers to activate a pop-up menu which will let you adjust what -columns are displayed. You can drag the column headers to adjust their -order. You can click them to sort by the field displayed in the column. -You can also save the result list in CSV format. - -**Changing the GUI geometry.** - -It is possible to configure the GUI in wide form factor by dragging the -toolbars to one of the sides (their location is remembered between -sessions), and moving the category filters to a menu (can be set in the -Preferences > GUI configuration > User interface panel). - -**Query explanation.** - -You can get an exact description of what the query looked for, including -stem expansion, and Boolean operators used, by clicking on the result -list header. - -**Advanced search history.** - -As of RCL 1.18, you can display any of the last 100 complex searches -performed by using the up and down arrow keys while the advanced search -panel is active. - -**Browsing the result list inside a preview window.** - -Entering Shift-Down or Shift-Up (Shift + an arrow key) in a preview -window will display the next or the previous document from the result -list. Any secondary search currently active will be executed on the new -document. - -**Scrolling the result list from the keyboard.** - -You can use PageUp and PageDown to scroll the result list, Shift+Home to -go back to the first page. These work even while the focus is in the -search entry. - -**Result table: moving the focus to the table.** - -You can use Ctrl-r to move the focus from the search entry to the table, -and then use the arrow keys to change the current row. Ctrl-Shift-s -returns to the search. - -**Result table: open / preview.** - -With the focus in the result table, you can use Ctrl-o to open the -document from the current row, Ctrl-Shift-o to open the document and -close ``recoll``, Ctrl-d to preview the document. - -**Editing a new search while the focus is not in the search entry.** - -You can use the Ctrl-Shift-S shortcut to return the cursor to the search -entry (and select the current search text), while the focus is anywhere -in the main window. - -**Forced opening of a preview window.** - -You can use Shift+Click on a result list ``Preview`` link to force the -creation of a preview window instead of a new tab in the existing one. - -**Closing previews.** - -Entering Ctrl-W in a tab will close it (and, for the last tab, close the -preview window). Entering Esc will close the preview window and all its -tabs. - -**Printing previews.** - -Entering Ctrl-P in a preview window will print the currently displayed -text. - -**Quitting.** - -Entering Ctrl-Q almost anywhere will close the application. - -Saving and restoring queries (1.21 and later) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Both simple and advanced query dialogs save recent history, but the -amount is limited: old queries will eventually be forgotten. Also, -important queries may be difficult to find among others. This is why -both types of queries can also be explicitely saved to files, from the -GUI menus: File > Save last query / Load last query - -The default location for saved queries is a subdirectory of the current -configuration directory, but saved queries are ordinary files and can be -written or moved anywhere. - -Some of the saved query parameters are part of the preferences (e.g. -``autophrase`` or the active external indexes), and may differ when the -query is loaded from the time it was saved. In this case, RCL will warn -of the differences, but will not change the user preferences. - -Customizing the search interface -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can customize some aspects of the search interface by using the GUI -configuration entry in the Preferences menu. - -There are several tabs in the dialog, dealing with the interface itself, -the parameters used for searching and returning results, and what -indexes are searched. - -**User interface parameters:.** - -- Highlight color for query terms: Terms from the user query are - highlighted in the result list samples and the preview window. The - color can be chosen here. Any Qt color string should work (ie - ``red``, ``#ff0000``). The default is ``blue``. - -- Style sheet: The name of a Qt style sheet text file which is applied - to the whole Recoll application on startup. The default value is - empty, but there is a skeleton style sheet (``recoll.qss``) inside - the ``/usr/share/recoll/examples`` directory. Using a style sheet, - you can change most ``recoll`` graphical parameters: colors, fonts, - etc. See the sample file for a few simple examples. - - You should be aware that parameters (e.g.: the background color) set - inside the RCL GUI style sheet will override global system - preferences, with possible strange side effects: for example if you - set the foreground to a light color and the background to a dark one - in the desktop preferences, but only the background is set inside the - RCL style sheet, and it is light too, then text will appear - light-on-light inside the RCL GUI. - -- Maximum text size highlighted for preview Inserting highlights on - search term inside the text before inserting it in the preview window - involves quite a lot of processing, and can be disabled over the - given text size to speed up loading. - -- Prefer HTML to plain text for preview if set, Recoll will display - HTML as such inside the preview window. If this causes problems with - the Qt HTML display, you can uncheck it to display the plain text - version instead. - -- Activate links in preview if set, Recoll will turn HTTP links found - inside plain text into proper HTML anchors, and clicking a link - inside a preview window will start the default browser on the link - target. - -- Plain text to HTML line style: when displaying plain text inside the - preview window, RCL tries to preserve some of the original text line - breaks and indentation. It can either use PRE HTML tags, which will - well preserve the indentation but will force horizontal scrolling for - long lines, or use BR tags to break at the original line breaks, - which will let the editor introduce other line breaks according to - the window width, but will lose some of the original indentation. The - third option has been available in recent releases and is probably - now the best one: use PRE tags with line wrapping. - -- Choose editor application: this opens a dialog which allows you to - select the application to be used to open each MIME type. The default - is to use the ``xdg-open`` utility, but you can use this dialog to - override it, setting exceptions for MIME types that will still be - opened according to RCL preferences. This is useful for passing - parameters like page numbers or search strings to applications that - support them (e.g. evince). This cannot be done with ``xdg-open`` - which only supports passing one parameter. - -- Disable Qt autocompletion in search entry: this will disable the - completion popup. Il will only appear, and display the full history, - either if you enter only white space in the search area, or if you - click the clock button on the right of the area. - -- Document filter choice style: this will let you choose if the - document categories are displayed as a list or a set of buttons, or a - menu. - -- Start with simple search mode: this lets you choose the value of the - simple search type on program startup. Either a fixed value (e.g. - ``Query Language``, or the value in use when the program last exited. - -- Start with advanced search dialog open: If you use this dialog - frequently, checking the entries will get it to open when recoll - starts. - -- Remember sort activation state if set, Recoll will remember the sort - tool stat between invocations. It normally starts with sorting - disabled. - -**Result list parameters:.** - -- Number of results in a result page - -- Result list font: There is quite a lot of information shown in the - result list, and you may want to customize the font and/or font size. - The rest of the fonts used by RCL are determined by your generic Qt - config (try the ``qtconfig`` command). - -- Edit result list paragraph format string: allows you to change the - presentation of each result list entry. See the `result list - customisation section <#RCL.SEARCH.GUI.CUSTOM.RESLIST>`__. - -- Edit result page HTML header insert: allows you to define text - inserted at the end of the result page HTML header. More detail in - the `result list customisation - section. <#RCL.SEARCH.GUI.CUSTOM.RESLIST>`__ - -- Date format: allows specifying the format used for displaying dates - inside the result list. This should be specified as an strftime() - string (man strftime). - -- Abstract snippet separator: for synthetic abstracts built from index - data, which are usually made of several snippets from different parts - of the document, this defines the snippet separator, an ellipsis by - default. - -**Search parameters:.** - -- Hide duplicate results: decides if result list entries are shown for - identical documents found in different places. - -- Stemming language: stemming obviously depends on the document's - language. This listbox will let you chose among the stemming - databases which were built during indexing (this is set in the `main - configuration file <#RCL.INSTALL.CONFIG.RECOLLCONF>`__), or later - added with ``recollindex - -s`` (See the recollindex manual). Stemming languages - which are dynamically added will be deleted at the next indexing pass - unless they are also added in the configuration file. - -- Automatically add phrase to simple searches: a phrase will be - automatically built and added to simple searches when looking for - ``Any - terms``. This will give a relevance boost to the - results where the search terms appear as a phrase (consecutive and in - order). - -- Autophrase term frequency threshold percentage: very frequent terms - should not be included in automatic phrase searches for performance - reasons. The parameter defines the cutoff percentage (percentage of - the documents where the term appears). - -- Replace abstracts from documents: this decides if we should - synthesize and display an abstract in place of an explicit abstract - found within the document itself. - -- Dynamically build abstracts: this decides if RCL tries to build - document abstracts (lists of *snippets*) when displaying the result - list. Abstracts are constructed by taking context from the document - information, around the search terms. - -- Synthetic abstract size: adjust to taste... - -- Synthetic abstract context words: how many words should be displayed - around each term occurrence. - -- Query language magic file name suffixes: a list of words which - automatically get turned into ``ext:xxx`` file name suffix clauses - when starting a query language query (ie: ``doc xls - xlsx...``). This will save some typing for people who - use file types a lot when querying. - -**External indexes:.** - -This panel will let you browse for additional indexes that you may want -to search. External indexes are designated by their database directory -(ie: ``/home/someothergui/.recoll/xapiandb``, -``/usr/local/recollglobal/xapiandb``). - -Once entered, the indexes will appear in the External indexes list, and -you can chose which ones you want to use at any moment by checking or -unchecking their entries. - -Your main database (the one the current configuration indexes to), is -always implicitly active. If this is not desirable, you can set up your -configuration so that it indexes, for example, an empty directory. An -alternative indexer may also need to implement a way of purging the -index from stale data, - -The result list format -^^^^^^^^^^^^^^^^^^^^^^ - -Newer versions of Recoll (from 1.17) normally use WebKit HTML widgets -for the result list and the `snippets -window <#RCL.SEARCH.GUI.RESULTLIST.MENU.SNIPPETS>`__ (this may be -disabled at build time). Total customisation is possible with full -support for CSS and Javascript. Conversely, there are limits to what you -can do with the older Qt QTextBrowser, but still, it is possible to -decide what data each result will contain, and how it will be displayed. - -The result list presentation can be exhaustively customized by adjusting -two elements: - -- The paragraph format - -- HTML code inside the header section. For versions 1.21 and later, - this is also used for the `snippets - window <#RCL.SEARCH.GUI.RESULTLIST.MENU.SNIPPETS>`__ - -The paragraph format and the header fragment can be edited from the -Result list tab of the GUI configuration. - -The header fragment is used both for the result list and the snippets -window. The snippets list is a table and has a ``snippets`` class -attribute. Each paragraph in the result list is a table, with class -``respar``, but this can be changed by editing the paragraph format. - -There are a few examples on the `page about customising the result -list `__ on the RCL web site. - -The paragraph format -'''''''''''''''''''' - -This is an arbitrary HTML string where the following printf-like ``%`` -substitutions will be performed: - -- **%A.** - - Abstract - -- **%D.** - - Date - -- **%I.** - - Icon image name. This is normally determined from the MIME type. The - associations are defined inside the ```mimeconf`` configuration - file <#RCL.INSTALL.CONFIG.MIMECONF>`__. If a thumbnail for the file - is found at the standard Freedesktop location, this will be displayed - instead. - -- **%K.** - - Keywords (if any) - -- **%L.** - - Precooked Preview, Edit, and possibly Snippets links - -- **%M.** - - MIME type - -- **%N.** - - result Number inside the result page - -- **%P.** - - Parent folder Url. In the case of an embedded document, this is the - parent folder for the top level container file. - -- **%R.** - - Relevance percentage - -- **%S.** - - Size information - -- **%T.** - - Title or Filename if not set. - -- **%t.** - - Title or empty. - -- **%(filename).** - - File name. - -- **%U.** - - Url - -The format of the Preview, Edit, and Snippets links is -````, ```` and ```` where -docnum (%N) expands to the document number inside the result page). - -A link target defined as ``"F%N"`` will open the document corresponding -to the ``%P`` parent folder expansion, usually creating a file manager -window on the folder where the container file resides. E.g.: - -:: - - %P - -A link target defined as ``R%N|scriptname`` will run the corresponding -script on the result file (if the document is embedded, the script will -be started on the top-level parent). See the `section about defining -scripts <#RCL.SEARCH.GUI.RUNSCRIPT>`__. - -In addition to the predefined values above, all strings like -``%(fieldname)`` will be replaced by the value of the field named -``fieldname`` for this document. Only stored fields can be accessed in -this way, the value of indexed but not stored fields is not known at -this point in the search process (see `field -configuration <#RCL.PROGRAM.FIELDS>`__). There are currently very few -fields stored by default, apart from the values above (only ``author`` -and ``filename``), so this feature will need some custom local -configuration to be useful. An example candidate would be the -``recipient`` field which is generated by the message input handlers. - -The default value for the paragraph format string is: - -:: - - "\n" - "\n" - "\n" - "\n" - "
%L  %S   %T
\n" - "%M %D    %U %i
\n" - "%A %K
\n" - - -You may, for example, try the following for a more web-like experience: - -:: - - %T
- %A%U - %S - %L - - -Note that the P%N link in the above paragraph makes the title a preview -link. Or the clean looking: - -:: - - %L %R -   %T&
%S  - %U - - -
%A
%K - - -These samples, and some others are `on the web site, with pictures to -show how they look. `__ - -It is also possible to `define the value of the snippet separator inside -the abstract section <#RCL.SEARCH.GUI.CUSTOM.ABSSEP>`__. - -Searching with the KDE KIO slave --------------------------------- - -What's this -~~~~~~~~~~~ - -The RCL KIO slave allows performing a RCL search by entering an -appropriate URL in a KDE open dialog, or with an HTML-based interface -displayed in ``Konqueror``. - -The HTML-based interface is similar to the Qt-based interface, but -slightly less powerful for now. Its advantage is that you can perform -your search while staying fully within the KDE framework: drag and drop -from the result list works normally and you have your normal choice of -applications for opening files. - -The alternative interface uses a directory view of search results. Due -to limitations in the current KIO slave interface, it is currently not -obviously useful (to me). - -The interface is described in more detail inside a help file which you -can access by entering ``recoll:/`` inside the ``konqueror`` URL line -(this works only if the recoll KIO slave has been previously installed). - -The instructions for building this module are located in the source -tree. See: ``kde/kio/recoll/00README.txt``. Some Linux distributions do -package the kio-recoll module, so check before diving into the build -process, maybe it's already out there ready for one-click installation. - -Searchable documents -~~~~~~~~~~~~~~~~~~~~ - -As a sample application, the RCL KIO slave could allow preparing a set -of HTML documents (for example a manual) so that they become their own -search interface inside ``konqueror``. - -This can be done by either explicitly inserting -```` links around some document areas, or -automatically by adding a very small javascript program to the -documents, like the following example, which would initiate a search by -double-clicking any term: - -:: - - - .... - - - - -Searching on the command line ------------------------------ - -There are several ways to obtain search results as a text stream, -without a graphical interface: - -- By passing option ``-t`` to the ``recoll`` program, or by calling it - as ``recollq`` (through a link). - -- By using the ``recollq`` program. - -- By writing a custom Python program, using the `Recoll Python - API <#RCL.PROGRAM.PYTHONAPI>`__. - -The first two methods work in the same way and accept/need the same -arguments (except for the additional ``-t`` to ``recoll``). The query to -be executed is specified as command line arguments. - -``recollq`` is not built by default. You can use the ``Makefile`` in the -``query`` directory to build it. This is a very simple program, and if -you can program a little c++, you may find it useful to taylor its -output format to your needs. Not that recollq is only really useful on -systems where the Qt libraries (or even the X11 ones) are not available. -Otherwise, just use ``recoll - -t``, which takes the exact same parameters and options which are -described for ``recollq`` - -``recollq`` has a man page (not installed by default, look in the -``doc/man`` directory). The Usage string is as follows: - -:: - - recollq: usage: - -P: Show the date span for all the documents present in the index - [-o|-a|-f] [-q] - Runs a recoll query and displays result lines. - Default: will interpret the argument(s) as a xesam query string - query may be like: - implicit AND, Exclusion, field spec: t1 -t2 title:t3 - OR has priority: t1 OR t2 t3 OR t4 means (t1 OR t2) AND (t3 OR t4) - Phrase: "t1 t2" (needs additional quoting on cmd line) - -o Emulate the GUI simple search in ANY TERM mode - -a Emulate the GUI simple search in ALL TERMS mode - -f Emulate the GUI simple search in filename mode - -q is just ignored (compatibility with the recoll GUI command line) - Common options: - -c : specify config directory, overriding $RECOLL_CONFDIR - -d also dump file contents - -n [first-] define the result slice. The default value for [first] - is 0. Without the option, the default max count is 2000. - Use n=0 for no limit - -b : basic. Just output urls, no mime types or titles - -Q : no result lines, just the processed query and result count - -m : dump the whole document meta[] array for each result - -A : output the document abstracts - -S fld : sort by field - -s stemlang : set stemming language to use (must exist in index...) - Use -s "" to turn off stem expansion - -D : sort descending - -i : additional index, several can be given - -e use url encoding (%xx) for urls - -F : output exactly these fields for each result. - The field values are encoded in base64, output in one line and - separated by one space character. This is the recommended format - for use by other programs. Use a normal query with option -m to - see the field names. - - -Sample execution: - -:: - - recollq 'ilur -nautique mime:text/html' - Recoll query: ((((ilur:(wqf=11) OR ilurs) AND_NOT (nautique:(wqf=11) - OR nautiques OR nautiqu OR nautiquement)) FILTER Ttext/html)) - 4 results - text/html [file:///Users/uncrypted-dockes/projets/bateaux/ilur/comptes.html] [comptes.html] 18593 bytes - text/html [file:///Users/uncrypted-dockes/projets/nautique/webnautique/articles/ilur1/index.html] [Constructio... - text/html [file:///Users/uncrypted-dockes/projets/pagepers/index.html] [psxtcl/writemime/recoll]... - text/html [file:///Users/uncrypted-dockes/projets/bateaux/ilur/factEtCie/recu-chasse-maree.... - - -Using Synonyms (1.22) ---------------------- - -**Term synonyms:.** - -there are a number of ways to use term synonyms for searching text: - -- At index creation time, they can be used to alter the indexed terms, - either increasing or decreasing their number, by expanding the - original terms to all synonyms, or by reducing all synonym terms to a - canonical one. - -- At query time, they can be used to match texts containing terms which - are synonyms of the ones specified by the user, either by expanding - the query for all synonyms, or by reducing the user entry to - canonical terms (the latter only works if the corresponding - processing has been performed while creating the index). - -RCL only uses synonyms at query time. A user query term which part of a -synonym group will be optionally expanded into an ``OR`` query for all -terms in the group. - -Synonym groups are defined inside ordinary text files. Each line in the -file defines a group. - -Example: - -:: - - hi hello "good morning" - - # not sure about "au revoir" though. Is this english ? - bye goodbye "see you" \ - "au revoir" - - -As usual, lines beginning with a ``#`` are comments, empty lines are -ignored, and lines can be continued by ending them with a backslash. - -Multi-word synonyms are supported, but be aware that these will generate -phrase queries, which may degrade performance and will disable stemming -expansion for the phrase terms. - -The synonyms file can be specified in the Search parameters tab of the -GUI configuration Preferences menu entry, or as an option for -command-line searches. - -Once the file is defined, the use of synonyms can be enabled or disabled -directly from the Preferences menu. - -The synonyms are searched for matches with user terms after the latter -are stem-expanded, but the contents of the synonyms file itself is not -subjected to stem expansion. This means that a match will not be found -if the form present in the synonyms file is not present anywhere in the -document set. - -The synonyms function is probably not going to help you find your -letters to Mr. Smith. It is best used for domain-specific searches. For -example, it was initially suggested by a user performing searches among -historical documents: the synonyms file would contains nicknames and -aliases for each of the persons of interest. - -Path translations ------------------ - -In some cases, the document paths stored inside the index do not match -the actual ones, so that document previews and accesses will fail. This -can occur in a number of circumstances: - -- When using multiple indexes it is a relatively common occurrence that - some will actually reside on a remote volume, for exemple mounted via - NFS. In this case, the paths used to access the documents on the - local machine are not necessarily the same than the ones used while - indexing on the remote machine. For example, ``/home/me`` may have - been used as a ``topdirs`` elements while indexing, but the directory - might be mounted as ``/net/server/home/me`` on the local machine. - -- The case may also occur with removable disks. It is perfectly - possible to configure an index to live with the documents on the - removable disk, but it may happen that the disk is not mounted at the - same place so that the documents paths from the index are invalid. - -- As a last exemple, one could imagine that a big directory has been - moved, but that it is currently inconvenient to run the indexer. - -RCL has a facility for rewriting access paths when extracting the data -from the index. The translations can be defined for the main index and -for any additional query index. - -The path translation facility will be useful whenever the documents -paths seen by the indexer are not the same as the ones which should be -used at query time. - -In the above NFS example, RCL could be instructed to rewrite any -``file:///home/me`` URL from the index to -``file:///net/server/home/me``, allowing accesses from the client. - -The translations are defined in the -```ptrans`` <#RCL.INSTALL.CONFIG.PTRANS>`__ configuration file, which -can be edited by hand or from the GUI external indexes configuration -dialog: Preferences > External index dialog, then click the Paths -translations button on the right below the index list. - - **Note** - - Due to a current bug, the GUI must be restarted after changing the - ``ptrans`` values (even when they were changed from the GUI). - -The query language ------------------- - -The query language processor is activated in the GUI simple search entry -when the search mode selector is set to Query Language. It can also be -used with the KIO slave or the command line search. It broadly has the -same capabilities as the complex search interface in the GUI. - -The language was based on the now defunct -`Xesam `__ user -search language specification. - -If the results of a query language search puzzle you and you doubt what -has been actually searched for, you can use the GUI ``Show Query`` link -at the top of the result list to check the exact query which was finally -executed by Xapian. - -Here follows a sample request that we are going to explain: - -:: - - author:"john doe" Beatles OR Lennon Live OR Unplugged -potatoes - - -This would search for all documents with John Doe appearing as a phrase -in the author field (exactly what this is would depend on the document -type, ie: the ``From:`` header, for an email message), and containing -either beatles or lennon and either live or unplugged but not potatoes -(in any part of the document). - -An element is composed of an optional field specification, and a value, -separated by a colon (the field separator is the last colon in the -element). Examples: Eugenie, author:balzac, dc:title:grandet -dc:title:"eugenie grandet" - -The colon, if present, means "contains". Xesam defines other relations, -which are mostly unsupported for now (except in special cases, described -further down). - -All elements in the search entry are normally combined with an implicit -AND. It is possible to specify that elements be OR'ed instead, as in -Beatles ``OR`` Lennon. The ``OR`` must be entered literally (capitals), -and it has priority over the AND associations: word1 word2 ``OR`` word3 -means word1 AND (word2 ``OR`` word3) not (word1 AND word2) ``OR`` word3. - -RCL versions 1.21 and later, allow using parentheses to group elements, -which will sometimes make things clearer, and may allow expressing -combinations which would have been difficult otherwise. - -An element preceded by a ``-`` specifies a term that should *not* -appear. - -As usual, words inside quotes define a phrase (the order of words is -significant), so that title:"prejudice pride" is not the same as -title:prejudice title:pride, and is unlikely to find a result. - -Words inside phrases and capitalized words are not stem-expanded. -Wildcards may be used anywhere inside a term. Specifying a wild-card on -the left of a term can produce a very slow search (or even an incorrect -one if the expansion is truncated because of excessive size). Also see -`More about wildcards <#RCL.SEARCH.WILDCARDS>`__. - -To save you some typing, recent RCL versions (1.20 and later) interpret -a comma-separated list of terms as an AND list inside the field. Use -slash characters ('/') for an OR list. No white space is allowed. So - -:: - - author:john,lennon - -will search for documents with ``john`` and ``lennon`` inside the -``author`` field (in any order), and - -:: - - author:john/ringo - -would search for ``john`` or ``ringo``. - -Modifiers can be set on a double-quote value, for example to specify a -proximity search (unordered). See `the modifier -section <#RCL.SEARCH.LANG.MODIFIERS>`__. No space must separate the -final double-quote and the modifiers value, e.g. "two one"po10 - -RCL currently manages the following default fields: - -- ``title``, ``subject`` or ``caption`` are synonyms which specify data - to be searched for in the document title or subject. - -- ``author`` or ``from`` for searching the documents originators. - -- ``recipient`` or ``to`` for searching the documents recipients. - -- ``keyword`` for searching the document-specified keywords (few - documents actually have any). - -- ``filename`` for the document's file name. This is not necessarily - set for all documents: internal documents contained inside a compound - one (for example an EPUB section) do not inherit the container file - name any more, this was replaced by an explicit field (see next). - Sub-documents can still have a specific ``filename``, if it is - implied by the document format, for example the attachment file name - for an email attachment. - -- ``containerfilename``. This is set for all documents, both top-level - and contained sub-documents, and is always the name of the filesystem - directory entry which contains the data. The terms from this field - can only be matched by an explicit field specification (as opposed to - terms from ``filename`` which are also indexed as general document - content). This avoids getting matches for all the sub-documents when - searching for the container file name. - -- ``ext`` specifies the file name extension (Ex: ``ext:html``) - -RCL 1.20 and later have a way to specify aliases for the field names, -which will save typing, for example by aliasing ``filename`` to fn or -``containerfilename`` to cfn. See the `section about the ``fields`` -file <#RCL.INSTALL.CONFIG.FIELDS>`__ - -The document input handlers used while indexing have the possibility to -create other fields with arbitrary names, and aliases may be defined in -the configuration, so that the exact field search possibilities may be -different for you if someone took care of the customisation. - -The field syntax also supports a few field-like, but special, criteria: - -- ``dir`` for filtering the results on file location (Ex: - ``dir:/home/me/somedir``). ``-dir`` also works to find results not in - the specified directory (release >= 1.15.8). Tilde expansion will be - performed as usual (except for a bug in versions 1.19 to 1.19.11p1). - Wildcards will be expanded, but please `have a - look <#RCL.SEARCH.WILDCARDS.PATH>`__ at an important limitation of - wildcards in path filters. - - Relative paths also make sense, for example, ``dir:share/doc`` would - match either ``/usr/share/doc`` or ``/usr/local/share/doc`` - - Several ``dir`` clauses can be specified, both positive and negative. - For example the following makes sense: - - :: - - dir:recoll dir:src -dir:utils -dir:common - - - This would select results which have both ``recoll`` and ``src`` in - the path (in any order), and which have not either ``utils`` or - ``common``. - - You can also use ``OR`` conjunctions with ``dir:`` clauses. - - A special aspect of ``dir`` clauses is that the values in the index - are not transcoded to UTF-8, and never lower-cased or unaccented, but - stored as binary. This means that you need to enter the values in the - exact lower or upper case, and that searches for names with - diacritics may sometimes be impossible because of character set - conversion issues. Non-ASCII UNIX file paths are an unending source - of trouble and are best avoided. - - You need to use double-quotes around the path value if it contains - space characters. - -- ``size`` for filtering the results on file size. Example: - ``size<10000``. You can use ``<``, ``>`` or ``=`` as operators. You - can specify a range like the following: ``size>100 size<1000``. The - usual ``k/K, m/M, g/G, t/T`` can be used as (decimal) multipliers. - Ex: ``size>1k`` to search for files bigger than 1000 bytes. - -- ``date`` for searching or filtering on dates. The syntax for the - argument is based on the ISO8601 standard for dates and time - intervals. Only dates are supported, no times. The general syntax is - 2 elements separated by a ``/`` character. Each element can be a date - or a period of time. Periods are specified as - ``P``\ n\ ``Y``\ n\ ``M``\ n\ ``D``. The n numbers are the respective - numbers of years, months or days, any of which may be missing. Dates - are specified as YYYY-MM-DD. The days and months parts may be - missing. If the ``/`` is present but an element is missing, the - missing element is interpreted as the lowest or highest date in the - index. Examples: - - - ``2001-03-01/2002-05-01`` the basic syntax for an interval of - dates. - - - ``2001-03-01/P1Y2M`` the same specified with a period. - - - ``2001/`` from the beginning of 2001 to the latest date in the - index. - - - ``2001`` the whole year of 2001 - - - ``P2D/`` means 2 days ago up to now if there are no documents with - dates in the future. - - - ``/2003`` all documents from 2003 or older. - - Periods can also be specified with small letters (ie: p2y). - -- ``mime`` or ``format`` for specifying the MIME type. These clauses - are processed besides the normal Boolean logic of the search. - Multiple values will be OR'ed (instead of the normal AND). You can - specify types to be excluded, with the usual ``-``, and use - wildcards. Example: mime:text/\* -mime:text/plain Specifying an - explicit boolean operator before a ``mime`` specification is not - supported and will produce strange results. - -- ``type`` or ``rclcat`` for specifying the category (as in - text/media/presentation/etc.). The classification of MIME types in - categories is defined in the RCL configuration (``mimeconf``), and - can be modified or extended. The default category names are those - which permit filtering results in the main GUI screen. Categories are - OR'ed like MIME types above, and can be negated with ``-``. - - **Note** - - ``mime``, ``rclcat``, ``size`` and ``date`` criteria always affect - the whole query (they are applied as a final filter), even if set - with other terms inside a parenthese. - - **Note** - - ``mime`` (or the equivalent ``rclcat``) is the *only* field with an - ``OR`` default. You do need to use ``OR`` with ``ext`` terms for - example. - -Range clauses -~~~~~~~~~~~~~ - -RCL 1.24 and later support range clauses on fields which have been -configured to support it. No default field uses them currently, so this -paragraph is only interesting if you modified the fields configuration -and possibly use a custom input handler. - -A range clause looks like one of the following: - -:: - - myfield:small..big - myfield:small.. - myfield:..big - - -The nature of the clause is indicated by the two dots ``..``, and the -effect is to filter the results for which the myfield value is in the -possibly open-ended interval. - -See the section about the ```fields`` configuration -file <#RCL.INSTALL.CONFIG.FIELDS>`__ for the details of configuring a -field for range searches (list them in the [values] section). - -Modifiers -~~~~~~~~~ - -Some characters are recognized as search modifiers when found -immediately after the closing double quote of a phrase, as in -``"some term"modifierchars``. The actual "phrase" can be a single term -of course. Supported modifiers: - -- ``l`` can be used to turn off stemming (mostly makes sense with ``p`` - because stemming is off by default for phrases). - -- ``s`` can be used to turn off synonym expansion, if a synonyms file - is in place (only for RCL 1.22 and later). - -- ``o`` can be used to specify a "slack" for phrase and proximity - searches: the number of additional terms that may be found between - the specified ones. If ``o`` is followed by an integer number, this - is the slack, else the default is 10. - -- ``p`` can be used to turn the default phrase search into a proximity - one (unordered). Example: ``"order any in"p`` - -- ``C`` will turn on case sensitivity (if the index supports it). - -- ``D`` will turn on diacritics sensitivity (if the index supports it). - -- A weight can be specified for a query element by specifying a decimal - value at the start of the modifiers. Example: ``"Important"2.5``. - -Search case and diacritics sensitivity --------------------------------------- - -For RCL versions 1.18 and later, and *when working with a raw index* -(not the default), searches can be sensitive to character case and -diacritics. How this happens is controlled by configuration variables -and what search data is entered. - -The general default is that searches entered without upper-case or -accented characters are insensitive to case and diacritics. An entry of -``resume`` will match any of ``Resume``, ``RESUME``, ``résumé``, -``Résumé`` etc. - -Two configuration variables can automate switching on sensitivity (they -were documented but actually did nothing until RCL 1.22): - -autodiacsens - If this is set, search sensitivity to diacritics will be turned on - as soon as an accented character exists in a search term. When the - variable is set to true, ``resume`` will start a - diacritics-unsensitive search, but ``résumé`` will be matched - exactly. The default value is *false*. - -autocasesens - If this is set, search sensitivity to character case will be turned - on as soon as an upper-case character exists in a search term - *except for the first one*. When the variable is set to true, ``us`` - or ``Us`` will start a diacritics-unsensitive search, but ``US`` - will be matched exactly. The default value is *true* (contrary to - ``autodiacsens``). - -As in the past, capitalizing the first letter of a word will turn off -its stem expansion and have no effect on case-sensitivity. - -You can also explicitely activate case and diacritics sensitivity by -using modifiers with the query language. ``C`` will make the term -case-sensitive, and ``D`` will make it diacritics-sensitive. Examples: - -:: - - "us"C - - -will search for the term ``us`` exactly (``Us`` will not be a match). - -:: - - "resume"D - - -will search for the term ``resume`` exactly (``résumé`` will not be a -match). - -When either case or diacritics sensitivity is activated, stem expansion -is turned off. Having both does not make much sense. - -Anchored searches and wildcards -------------------------------- - -Some special characters are interpreted by RCL in search strings to -expand or specialize the search. Wildcards expand a root term in -controlled ways. Anchor characters can restrict a search to succeed only -if the match is found at or near the beginning of the document or one of -its fields. - -More about wildcards -~~~~~~~~~~~~~~~~~~~~ - -All words entered in RCL search fields will be processed for wildcard -expansion before the request is finally executed. - -The wildcard characters are: - -- ``*`` which matches 0 or more characters. - -- ``?`` which matches a single character. - -- ``[]`` which allow defining sets of characters to be matched (ex: - ``[``\ ``abc``\ ``]`` matches a single character which may be 'a' or - 'b' or 'c', ``[``\ ``0-9``\ ``]`` matches any number. - -You should be aware of a few things when using wildcards. - -- Using a wildcard character at the beginning of a word can make for a - slow search because RCL will have to scan the whole index term list - to find the matches. However, this is much less a problem for field - searches, and queries like author:\*@domain.com can sometimes be very - useful. - -- For RCL version 18 only, when working with a raw index (preserving - character case and diacritics), the literal part of a wildcard - expression will be matched exactly for case and diacritics. This is - not true any more for versions 19 and later. - -- Using a ``*`` at the end of a word can produce more matches than you - would think, and strange search results. You can use the `term - explorer <#RCL.SEARCH.GUI.TERMEXPLORER>`__ tool to check what - completions exist for a given term. You can also see exactly what - search was performed by clicking on the link at the top of the result - list. In general, for natural language terms, stem expansion will - produce better results than an ending ``*`` (stem expansion is turned - off when any wildcard character appears in the term). - -Wildcards and path filtering -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Due to the way that RCL processes wildcards inside ``dir`` path -filtering clauses, they will have a multiplicative effect on the query -size. A clause containg wildcards in several paths elements, like, for -example, ``dir:``/home/me/\*/\*/docdir, will almost certainly fail if -your indexed tree is of any realistic size. - -Depending on the case, you may be able to work around the issue by -specifying the paths elements more narrowly, with a constant prefix, or -by using 2 separate ``dir:`` clauses instead of multiple wildcards, as -in ``dir:``/home/me ``dir:``\ docdir. The latter query is not equivalent -to the initial one because it does not specify a number of directory -levels, but that's the best we can do (and it may be actually more -useful in some cases). - -Anchored searches -~~~~~~~~~~~~~~~~~ - -Two characters are used to specify that a search hit should occur at the -beginning or at the end of the text. ``^`` at the beginning of a term or -phrase constrains the search to happen at the start, ``$`` at the end -force it to happen at the end. - -As this function is implemented as a phrase search it is possible to -specify a maximum distance at which the hit should occur, either through -the controls of the advanced search panel, or using the query language, -for example, as in: - -:: - - "^someterm"o10 - -which would force ``someterm`` to be found within 10 terms of the start -of the text. This can be combined with a field search as in -``somefield:"^someterm"o10`` or ``somefield:someterm$``. - -This feature can also be used with an actual phrase search, but in this -case, the distance applies to the whole phrase and anchor, so that, for -example, ``bla bla my unexpected - term`` at the beginning of the text would be a match for -``"^my term"o5``. - -Anchored searches can be very useful for searches inside somewhat -structured documents like scientific articles, in case explicit metadata -has not been supplied (a most frequent case), for example for looking -for matches inside the abstract or the list of authors (which occur at -the top of the document). - -Desktop integration -------------------- - -Being independant of the desktop type has its drawbacks: RCL desktop -integration is minimal. However there are a few tools available: - -- The KDE KIO Slave was described in a `previous - section <#RCL.SEARCH.KIO>`__. - -- If you use a recent version of Ubuntu Linux, you may find the `Ubuntu - Unity Lens <&FAQS;UnityLens>`__ module useful. - -- There is also an independantly developed `Krunner - plugin `__. - -Here follow a few other things that may help. - -Hotkeying recoll -~~~~~~~~~~~~~~~~ - -It is surprisingly convenient to be able to show or hide the RCL GUI -with a single keystroke. Recoll comes with a small Python script, based -on the libwnck window manager interface library, which will allow you to -do just this. The detailed instructions are on `this wiki -page <&FAQS;HotRecoll>`__. - -The KDE Kicker Recoll applet -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This is probably obsolete now. Anyway: - -The RCL source tree contains the source code to the recoll\_applet, a -small application derived from the find\_applet. This can be used to add -a small RCL launcher to the KDE panel. - -The applet is not automatically built with the main RCL programs, nor is -it included with the main source distribution (because the KDE build -boilerplate makes it relatively big). You can download its source from -the recoll.org download page. Use the omnipotent -``configure;make;make install`` incantation to build and install. - -You can then add the applet to the panel by right-clicking the panel and -choosing the Add applet entry. - -The recoll\_applet has a small text window where you can type a RCL -query (in query language form), and an icon which can be used to -restrict the search to certain types of files. It is quite primitive, -and launches a new recoll GUI instance every time (even if it is already -running). You may find it useful anyway. - -Removable volumes -================= - -RCL used to have no support for indexing removable volumes (portable -disks, USB keys, etc.). Recent versions have improved the situation and -support indexing removable volumes in two different ways: - -- By storing a volume index on the volume itself (RCL 1.24). - -- By indexing the volume in the main, fixed, index, and ensuring that - the volume data is not purged if the indexing runs while the volume - is mounted. (RCL 1.25.2). - -Indexing removable volumes in the main index --------------------------------------------- - -As of version 1.25.2, RCL has a simple way to ensure that the index data -for an absent volume will not be purged: the volume mount point must be -a member of the ``topdirs`` list, and the mount directory must be empty -(when the volume is not mounted). If ``recollindex`` finds that one of -the ``topdirs`` is empty when starting up, any existing data for the -tree will be preserved by the indexing pass (no purge for this area). - -Self contained volumes ----------------------- - -As of RCL 1.24, it has become easy to build self-contained datasets -including a RCL configuration directory and index together with the -indexed documents, and to move such a dataset around (for example -copying it to an USB drive), without having to adjust the configuration -for querying the index. - - **Note** - - This is a query-time feature only. The index must only be updated in - its original location. If an update is necessary in a different - location, the index must be reset. - -To make a long story short, here follows a script to create a RCL -configuration and index under a given directory (given as single -parameter). The resulting data set (files + recoll directory) can later -to be moved to a CDROM or thumb drive. Longer explanations come after -the script. - -:: - - #!/bin/sh - - fatal() - { - echo $*;exit 1 - } - usage() - { - fatal "Usage: init-recoll-volume.sh " - } - - test $# = 1 || usage - topdir=$1 - test -d "$topdir" || fatal $topdir should be a directory - - confdir="$topdir/recoll-config" - test ! -d "$confdir" || fatal $confdir should not exist - - mkdir "$confdir" - cd "$topdir" - topdir=`pwd` - cd "$confdir" - confdir=`pwd` - - (echo topdirs = '"'$topdir'"'; \ - echo orgidxconfdir = $topdir/recoll-config) > "$confdir/recoll.conf" - - recollindex -c "$confdir" - -The examples below will assume that you have a dataset under -``/home/me/mydata/``, with the index configuration and data stored -inside ``/home/me/mydata/recoll-confdir``. - -In order to be able to run queries after the dataset has been moved, you -must ensure the following: - -- The main configuration file must define the - `orgidxconfdir <#RCL.INSTALL.CONFIG.RECOLLCONF.ORGIDXCONFDIR>`__ - variable to be the original location of the configuration directory - (``orgidxconfdir=/home/me/mydata/recoll-confdir`` must be set inside - ``/home/me/mydata/recoll-confdir/recoll.conf`` in the example above). - -- The configuration directory must exist with the documents, somewhere - under the directory which will be moved. E.g. if you are moving - ``/home/me/mydata`` around, the configuration directory must exist - somewhere below this point, for example - ``/home/me/mydata/recoll-confdir``, or - ``/home/me/mydata/sub/recoll-confdir``. - -- You should keep the default locations for the index elements (they - are relative to the configuration directory by default). Only the - paths referring to the documents themselves (e.g. ``topdirs`` values) - should be absolute (in general, they are only used when indexing - anyway). - -Only the first point needs an explicit user action, the RCL defaults are -compatible with the second one, and the third is natural. - -If, after the move, the configuration directory needs to be copied out -of the dataset (for example because the thumb drive is too slow), you -can set the -`curidxconfdir <#RCL.INSTALL.CONFIG.RECOLLCONF.CURIDXCONFDIR>`__, -variable inside the copied configuration to define the location of the -moved one. For example if ``/home/me/mydata`` is now mounted onto -``/media/me/somelabel``, but the configuration directory and index has -been copied to ``/tmp/tempconfig``, you would set ``curidxconfdir`` to -``/media/me/somelabel/recoll-confdir`` inside -``/tmp/tempconfig/recoll.conf``. ``orgidxconfdir`` would still be -``/home/me/mydata/recoll-confdir`` in the original and the copy. - -If you are regularly copying the configuration out of the dataset, it -will be useful to write a script to automate the procedure. This can't -really be done inside RCL because there are probably many possible -variants. One example would be to copy the configuration to make it -writable, but keep the index data on the medium because it is too big - -in this case, the script would also need to set ``dbdir`` in the copied -configuration. - -The same set of modifications (RCL 1.24) has also made it possible to -run queries from a readonly configuration directory (with slightly -reduced function of course, such as not recording the query history). - -Programming interface -===================== - -RCL has an Application Programming Interface, usable both for indexing -and searching, currently accessible from the Python language. - -Another less radical way to extend the application is to write input -handlers for new types of documents. - -The processing of metadata attributes for documents (``fields``) is -highly configurable. - -Writing a document input handler --------------------------------- - - **Note** - - The small programs or pieces of code which handle the processing of - the different document types for RCL used to be called ``filters``, - which is still reflected in the name of the directory which holds - them and many configuration variables. They were named this way - because one of their primary functions is to filter out the - formatting directives and keep the text content. However these - modules may have other behaviours, and the term ``input handler`` is - now progressively substituted in the documentation. ``filter`` is - still used in many places though. - -RCL input handlers cooperate to translate from the multitude of input -document formats, simple ones as opendocument, acrobat, or compound ones -such as Zip or Email, into the final RCL indexing input format, which is -plain text (in many cases the processing pipeline has an intermediary -HTML step, which may be used for better previewing presentation). Most -input handlers are executable programs or scripts. A few handlers are -coded in C++ and live inside ``recollindex``. This latter kind will not -be described here. - -There are currently (since version 1.13) two kinds of external -executable input handlers: - -- Simple ``exec`` handlers run once and exit. They can be bare programs - like ``antiword``, or scripts using other programs. They are very - simple to write, because they just need to print the converted - document to the standard output. Their output can be plain text or - HTML. HTML is usually preferred because it can store metadata fields - and it allows preserving some of the formatting for the GUI preview. - However, these handlers have limitations: - - - They can only process one document per file. - - - The output MIME type must be known and fixed. - - - The character encoding, if relevant, must be known and fixed (or - possibly just depending on location). - -- Multiple ``execm`` handlers can process multiple files (sparing the - process startup time which can be very significant), or multiple - documents per file (e.g.: for archives or multi-chapter - publications). They communicate with the indexer through a simple - protocol, but are nevertheless a bit more complicated than the older - kind. Most of the new handlers are written in Python (exception: - ``rclimg`` which is written in Perl because ``exiftool`` has no real - Python equivalent). The Python handlers use common modules to factor - out the boilerplate, which can make them very simple in favorable - cases. The subdocuments output by these handlers can be directly - indexable (text or HTML), or they can be other simple or compound - documents that will need to be processed by another handler. - -In both cases, handlers deal with regular file system files, and can -process either a single document, or a linear list of documents in each -file. RCL is responsible for performing up to date checks, deal with -more complex embedding and other upper level issues. - -A simple handler returning a document in ``text/plain`` format, can -transfer no metadata to the indexer. Generic metadata, like document -size or modification date, will be gathered and stored by the indexer. - -Handlers that produce ``text/html`` format can return an arbitrary -amount of metadata inside HTML ``meta`` tags. These will be processed -according to the directives found in the ```fields`` configuration -file <#RCL.PROGRAM.FIELDS>`__. - -The handlers that can handle multiple documents per file return a single -piece of data to identify each document inside the file. This piece of -data, called an ``ipath`` will be sent back by RCL to extract the -document at query time, for previewing, or for creating a temporary file -to be opened by a viewer. These handlers can also return metadata either -as HTML ``meta`` tags, or as named data through the communication -protocol. - -The following section describes the simple handlers, and the next one -gives a few explanations about the ``execm`` ones. You could conceivably -write a simple handler with only the elements in the manual. This will -not be the case for the other ones, for which you will have to look at -the code. - -Simple input handlers -~~~~~~~~~~~~~~~~~~~~~ - -RCL simple handlers are usually shell-scripts, but this is in no way -necessary. Extracting the text from the native format is the difficult -part. Outputting the format expected by RCL is trivial. Happily enough, -most document formats have translators or text extractors which can be -called from the handler. In some cases the output of the translating -program is completely appropriate, and no intermediate shell-script is -needed. - -Input handlers are called with a single argument which is the source -file name. They should output the result to stdout. - -When writing a handler, you should decide if it will output plain text -or HTML. Plain text is simpler, but you will not be able to add metadata -or vary the output character encoding (this will be defined in a -configuration file). Additionally, some formatting may be easier to -preserve when previewing HTML. Actually the deciding factor is metadata: -RCL has a way to `extract metadata from the HTML header and use it for -field searches. <#RCL.PROGRAM.FILTERS.HTML>`__. - -The RECOLL\_FILTER\_FORPREVIEW environment variable (values ``yes``, -``no``) tells the handler if the operation is for indexing or -previewing. Some handlers use this to output a slightly different -format, for example stripping uninteresting repeated keywords (ie: -``Subject:`` for email) when indexing. This is not essential. - -You should look at one of the simple handlers, for example ``rclps`` for -a starting point. - -Don't forget to make your handler executable before testing ! - -"Multiple" handlers -~~~~~~~~~~~~~~~~~~~ - -If you can program and want to write an ``execm`` handler, it should not -be too difficult to make sense of one of the existing handlers. - -The existing handlers differ in the amount of helper code which they are -using: - -- ``rclimg`` is written in Perl and handles the execm protocol all by - itself (showing how trivial it is). - -- All the Python handlers share at least the ``rclexecm.py`` module, - which handles the communication. Have a look at, for example, - ``rclzip`` for a handler which uses ``rclexecm.py`` directly. - -- Most Python handlers which process single-document files by executing - another command are further abstracted by using the ``rclexec1.py`` - module. See for example ``rclrtf.py`` for a simple one, or - ``rcldoc.py`` for a slightly more complicated one (possibly executing - several commands). - -- Handlers which extract text from an XML document by using an XSLT - style sheet are now executed inside ``recollindex``, with only the - style sheet stored in the ``filters/`` directory. These can use a - single style sheet (e.g. ``abiword.xsl``), or two sheets for the data - and metadata (e.g. ``opendoc-body.xsl`` and ``opendoc-meta.xsl``). - The ``mimeconf`` configuration file defines how the sheets are used, - have a look. Before the C++ import, the xsl-based handlers used a - common module ``rclgenxslt.py``, it is still around but unused. The - handler for OpenXML presentations is still the Python version because - the format did not fit with what the C++ code does. It would be a - good base for another similar issue. - -There is a sample trivial handler based on ``rclexecm.py``, with many -comments, not actually used by RCL. It would index a text file as one -document per line. Look for ``rcltxtlines.py`` in the ``src/filters`` -directory in the online RCL `Git -repository `__ (the sample not -in the distributed release at the moment). - -You can also have a look at the slightly more complex ``rclzip`` which -uses Zip file paths as identifiers (``ipath``). - -``execm`` handlers sometimes need to make a choice for the nature of the -``ipath`` elements that they use in communication with the indexer. Here -are a few guidelines: - -- Use ASCII or UTF-8 (if the identifier is an integer print it, for - example, like printf %d would do). - -- If at all possible, the data should make some kind of sense when - printed to a log file to help with debugging. - -- RCL uses a colon (``:``) as a separator to store a complex path - internally (for deeper embedding). Colons inside the ``ipath`` - elements output by a handler will be escaped, but would be a bad - choice as a handler-specific separator (mostly, again, for debugging - issues). - -In any case, the main goal is that it should be easy for the handler to -extract the target document, given the file name and the ``ipath`` -element. - -``execm`` handlers will also produce a document with a null ``ipath`` -element. Depending on the type of document, this may have some -associated data (e.g. the body of an email message), or none (typical -for an archive file). If it is empty, this document will be useful -anyway for some operations, as the parent of the actual data documents. - -Telling RCL about the handler -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -There are two elements that link a file to the handler which should -process it: the association of file to MIME type and the association of -a MIME type with a handler. - -The association of files to MIME types is mostly based on name suffixes. -The types are defined inside the ```mimemap`` -file <#RCL.INSTALL.CONFIG.MIMEMAP>`__. Example: - -:: - - - .doc = application/msword - - -If no suffix association is found for the file name, RCL will try to -execute a system command (typically ``file -i`` or ``xdg-mime``) to -determine a MIME type. - -The second element is the association of MIME types to handlers in the -```mimeconf`` file <#RCL.INSTALL.CONFIG.MIMECONF>`__. A sample will -probably be better than a long explanation: - -:: - - - [index] - application/msword = exec antiword -t -i 1 -m UTF-8;\ - mimetype = text/plain ; charset=utf-8 - - application/ogg = exec rclogg - - text/rtf = exec unrtf --nopict --html; charset=iso-8859-1; mimetype=text/html - - application/x-chm = execm rclchm - - -The fragment specifies that: - -- ``application/msword`` files are processed by executing the - ``antiword`` program, which outputs ``text/plain`` encoded in - ``utf-8``. - -- ``application/ogg`` files are processed by the ``rclogg`` script, - with default output type (``text/html``, with encoding specified in - the header, or ``utf-8`` by default). - -- ``text/rtf`` is processed by ``unrtf``, which outputs ``text/html``. - The ``iso-8859-1`` encoding is specified because it is not the - ``utf-8`` default, and not output by ``unrtf`` in the HTML header - section. - -- ``application/x-chm`` is processed by a persistant handler. This is - determined by the ``execm`` keyword. - -Input handler output -~~~~~~~~~~~~~~~~~~~~ - -Both the simple and persistent input handlers can return any MIME type -to Recoll, which will further process the data according to the MIME -configuration. - -Most input filters filters produce either ``text/plain`` or -``text/html`` data. There are exceptions, for example, filters which -process archive file (``zip``, ``tar``, etc.) will usually return the -documents as they are found, without processing them further. - -There is nothing to say about ``text/plain`` output, except that its -character encoding should be consistent with what is specified in the -``mimeconf`` file. - -For filters producing HTML, the output could be very minimal like the -following example: - -:: - - - - - - - Some text content - - - - -You should take care to escape some characters inside the text by -transforming them into appropriate entities. At the very minimum, -"``&``" should be transformed into "``&``", "``<``" should be -transformed into "``<``". This is not always properly done by -external helper programs which output HTML, and of course never by those -which output plain text. - -When encapsulating plain text in an HTML body, the display of a preview -may be improved by enclosing the text inside ``

`` tags.
-
-The character set needs to be specified in the header. It does not need
-to be UTF-8 (RCL will take care of translating it), but it must be
-accurate for good results.
-
-RCL will process ``meta`` tags inside the header as possible document
-fields candidates. Documents fields can be processed by the indexer in
-different ways, for searching or displaying inside query results. This
-is described in a `following section. <#RCL.PROGRAM.FIELDS>`__
-
-By default, the indexer will process the standard header fields if they
-are present: ``title``, ``meta/description``, and ``meta/keywords`` are
-both indexed and stored for query-time display.
-
-A predefined non-standard ``meta`` tag will also be processed by RCL
-without further configuration: if a ``date`` tag is present and has the
-right format, it will be used as the document date (for display and
-sorting), in preference to the file modification date. The date format
-should be as follows:
-
-::
-
-              
-              or
-              
-            
-
-Example:
-
-::
-
-              
-            
-
-Input handlers also have the possibility to "invent" field names. This
-should also be output as meta tags:
-
-::
-
-              
-            
-
-You can embed HTML markup inside the content of custom fields, for
-improving the display inside result lists. In this case, add a (wildly
-non-standard) ``markup`` attribute to tell RCL that the value is HTML
-and should not be escaped for display.
-
-::
-
-              
-            
-
-As written above, the processing of fields is described in a `further
-section <#RCL.PROGRAM.FIELDS>`__.
-
-Persistent filters can use another, probably simpler, method to produce
-metadata, by calling the ``setfield()`` helper method. This avoids the
-necessity to produce HTML, and any issue with HTML quoting. See, for
-example, ``rclaudio`` in RCL 1.23 and later for an example of handler
-which outputs ``text/plain`` and uses ``setfield()`` to produce
-metadata.
-
-Page numbers
-~~~~~~~~~~~~
-
-The indexer will interpret ``^L`` characters in the handler output as
-indicating page breaks, and will record them. At query time, this allows
-starting a viewer on the right page for a hit or a snippet. Currently,
-only the PDF, Postscript and DVI handlers generate page breaks.
-
-Field data processing
----------------------
-
-``Fields`` are named pieces of information in or about documents, like
-``title``, ``author``, ``abstract``.
-
-The field values for documents can appear in several ways during
-indexing: either output by input handlers as ``meta`` fields in the HTML
-header section, or extracted from file extended attributes, or added as
-attributes of the ``Doc`` object when using the API, or again
-synthetized internally by RCL.
-
-The RCL query language allows searching for text in a specific field.
-
-RCL defines a number of default fields. Additional ones can be output by
-handlers, and described in the ``fields`` configuration file.
-
-Fields can be:
-
--  ``indexed``, meaning that their terms are separately stored in
-   inverted lists (with a specific prefix), and that a field-specific
-   search is possible.
-
--  ``stored``, meaning that their value is recorded in the index data
-   record for the document, and can be returned and displayed with
-   search results.
-
-A field can be either or both indexed and stored. This and other aspects
-of fields handling is defined inside the ``fields`` configuration file.
-
-Some fields may also designated as supporting range queries, meaning
-that the results may be selected for an interval of its values. See the
-`configuration section <#RCL.INSTALL.CONFIG.FIELDS>`__ for more details.
-
-The sequence of events for field processing is as follows:
-
--  During indexing, ``recollindex`` scans all ``meta`` fields in HTML
-   documents (most document types are transformed into HTML at some
-   point). It compares the name for each element to the configuration
-   defining what should be done with fields (the ``fields`` file)
-
--  If the name for the ``meta`` element matches one for a field that
-   should be indexed, the contents are processed and the terms are
-   entered into the index with the prefix defined in the ``fields``
-   file.
-
--  If the name for the ``meta`` element matches one for a field that
-   should be stored, the content of the element is stored with the
-   document data record, from which it can be extracted and displayed at
-   query time.
-
--  At query time, if a field search is performed, the index prefix is
-   computed and the match is only performed against appropriately
-   prefixed terms in the index.
-
--  At query time, the field can be displayed inside the result list by
-   using the appropriate directive in the definition of the `result list
-   paragraph format <#RCL.SEARCH.GUI.CUSTOM.RESLIST>`__. All fields are
-   displayed on the fields screen of the preview window (which you can
-   reach through the right-click menu). This is independant of the fact
-   that the search which produced the results used the field or not.
-
-You can find more information in the `section about the ``fields``
-file <#RCL.INSTALL.CONFIG.FIELDS>`__, or in comments inside the file.
-
-You can also have a look at the `example in the FAQs
-area <&FAQS;HandleCustomField>`__, detailing how one could add a *page
-count* field to pdf documents for displaying inside result lists.
-
-Python API
-----------
-
-Introduction
-~~~~~~~~~~~~
-
-The RCL Python programming interface can be used both for searching and
-for creating/updating an index. Bindings exist for Python2 and Python3.
-
-The search interface is used in a number of active projects: the RCL
-Gnome Shell Search Provider, the RCL Web UI, and the upmpdcli UPnP Media
-Server, in addition to many small scripts.
-
-The index update section of the API may be used to create and update RCL
-indexes on specific configurations (separate from the ones created by
-``recollindex``). The resulting databases can be queried alone, or in
-conjunction with regular ones, through the GUI or any of the query
-interfaces.
-
-The search API is modeled along the Python database API specification.
-There were two major changes along RCL versions:
-
--  The basis for the RCL API changed from Python database API version
-   1.0 (RCL versions up to 1.18.1), to version 2.0 (RCL 1.18.2 and
-   later).
-
--  The ``recoll`` module became a package (with an internal ``recoll``
-   module) as of RCL version 1.19, in order to add more functions. For
-   existing code, this only changes the way the interface must be
-   imported.
-
-We will describe the new API and package structure here. A paragraph at
-the end of this section will explain a few differences and ways to write
-code compatible with both versions.
-
-The ``recoll`` package now contains two modules:
-
--  The ``recoll`` module contains functions and classes used to query
-   (or update) the index.
-
--  The ``rclextract`` module contains functions and classes used at
-   query time to access document data.
-
-There is a good chance that your system repository has packages for the
-Recoll Python API, sometimes in a package separate from the main one
-(maybe named something like python-recoll). Else refer to the `Building
-from source chapter <#RCL.INSTALL.BUILDING>`__.
-
-As an introduction, the following small sample will run a query and list
-the title and url for each of the results. It would work with RCL 1.19
-and later. The ``python/samples`` source directory contains several
-examples of Python programming with RCL, exercising the extension more
-completely, and especially its data extraction features.
-
-::
-
-            #!/usr/bin/env python
-
-            from recoll import recoll
-
-            db = recoll.connect()
-            query = db.query()
-            nres = query.execute("some query")
-            results = query.fetchmany(20)
-            for doc in results:
-                print("%s %s" % (doc.url, doc.title))
-            
-
-You can also take a look at the source for the `Recoll
-WebUI `__,
-the `upmpdcli local media
-server `__,
-or the `Gnome Shell Search
-Provider `__.
-
-Interface elements
-~~~~~~~~~~~~~~~~~~
-
-A few elements in the interface are specific and and need an
-explanation.
-
-ipath
-    This data value (set as a field in the Doc object) is stored, along
-    with the URL, but not indexed by RCL. Its contents are not
-    interpreted by the index layer, and its use is up to the
-    application. For example, the RCL file system indexer uses the
-    ``ipath`` to store the part of the document access path internal to
-    (possibly imbricated) container documents. ``ipath`` in this case is
-    a vector of access elements (e.g, the first part could be a path
-    inside a zip file to an archive member which happens to be an mbox
-    file, the second element would be the message sequential number
-    inside the mbox etc.). ``url`` and ``ipath`` are returned in every
-    search result and define the access to the original document.
-    ``ipath`` is empty for top-level document/files (e.g. a PDF document
-    which is a filesystem file). The RCL GUI knows about the structure
-    of the ``ipath`` values used by the filesystem indexer, and uses it
-    for such functions as opening the parent of a given document.
-
-udi
-    An ``udi`` (unique document identifier) identifies a document.
-    Because of limitations inside the index engine, it is restricted in
-    length (to 200 bytes), which is why a regular URI cannot be used.
-    The structure and contents of the ``udi`` is defined by the
-    application and opaque to the index engine. For example, the
-    internal file system indexer uses the complete document path (file
-    path + internal path), truncated to length, the suppressed part
-    being replaced by a hash value. The ``udi`` is not explicit in the
-    query interface (it is used "under the hood" by the ``rclextract``
-    module), but it is an explicit element of the update interface.
-
-parent\_udi
-    If this attribute is set on a document when entering it in the
-    index, it designates its physical container document. In a
-    multilevel hierarchy, this may not be the immediate parent.
-    ``parent_udi`` is optional, but its use by an indexer may simplify
-    index maintenance, as RCL will automatically delete all children
-    defined by ``parent_udi == udi`` when the document designated by
-    ``udi`` is destroyed. e.g. if a ``Zip`` archive contains entries
-    which are themselves containers, like ``mbox`` files, all the
-    subdocuments inside the ``Zip`` file (mbox, messages, message
-    attachments, etc.) would have the same ``parent_udi``, matching the
-    ``udi`` for the ``Zip`` file, and all would be destroyed when the
-    ``Zip`` file (identified by its ``udi``) is removed from the index.
-    The standard filesystem indexer uses ``parent_udi``.
-
-Stored and indexed fields
-    The ```fields`` file <#RCL.INSTALL.CONFIG.FIELDS>`__ inside the RCL
-    configuration defines which document fields are either ``indexed``
-    (searchable), ``stored`` (retrievable with search results), or both.
-    Apart from a few standard/internal fields, only the ``stored``
-    fields are retrievable through the Python search interface.
-
-Python search interface
-~~~~~~~~~~~~~~~~~~~~~~~
-
-The recoll module
-^^^^^^^^^^^^^^^^^
-
-The ``connect()`` function connects to one or several RCL index(es) and
-returns a ``Db`` object.
-
-This call initializes the recoll module, and it should always be
-performed before any other call or object creation.
-
--  ``confdir`` may specify a configuration directory. The usual defaults
-   apply.
-
--  ``extra_dbs`` is a list of additional indexes (Xapian directories).
-
--  ``writable`` decides if we can index new data through this
-   connection.
-
-A Db object is created by a ``connect()`` call and holds a connection to
-a Recoll index.
-
-Db.close()
-    Closes the connection. You can't do anything with the ``Db`` object
-    after this.
-
-Db.query(), Db.cursor()
-    These aliases return a blank ``Query`` object for this index.
-
-Db.setAbstractParams(maxchars, contextwords)
-    Set the parameters used to build snippets (sets of keywords in
-    context text fragments). ``maxchars`` defines the maximum total size
-    of the abstract. ``contextwords`` defines how many terms are shown
-    around the keyword.
-
-Db.termMatch(match\_type, expr, field='', maxlen=-1, casesens=False,
-diacsens=False, lang='english')
-    Expand an expression against the index term list. Performs the basic
-    function from the GUI term explorer tool. ``match_type`` can be
-    either of ``wildcard``, ``regexp`` or ``stem``. Returns a list of
-    terms expanded from the input expression.
-
-A ``Query`` object (equivalent to a cursor in the Python DB API) is
-created by a ``Db.query()`` call. It is used to execute index searches.
-
-Query.sortby(fieldname, ascending=True)
-    Sort results by fieldname, in ascending or descending order. Must be
-    called before executing the search.
-
-Query.execute(query\_string, stemming=1, stemlang="english",
-fetchtext=False)
-    Starts a search for query\_string, a RCL search language string. If
-    the index stores the document texts and ``fetchtext`` is True, store
-    the document extracted text in ``doc.text``.
-
-Query.executesd(SearchData, fetchtext=False)
-    Starts a search for the query defined by the SearchData object. If
-    the index stores the document texts and ``fetchtext`` is True, store
-    the document extracted text in ``doc.text``.
-
-Query.fetchmany(size=query.arraysize)
-    Fetches the next ``Doc`` objects in the current search results, and
-    returns them as an array of the required size, which is by default
-    the value of the ``arraysize`` data member.
-
-Query.fetchone()
-    Fetches the next ``Doc`` object from the current search results.
-    Generates a StopIteration exception if there are no results left.
-
-Query.close()
-    Closes the query. The object is unusable after the call.
-
-Query.scroll(value, mode='relative')
-    Adjusts the position in the current result set. ``mode`` can be
-    ``relative`` or ``absolute``.
-
-Query.getgroups()
-    Retrieves the expanded query terms as a list of pairs. Meaningful
-    only after executexx In each pair, the first entry is a list of user
-    terms (of size one for simple terms, or more for group and phrase
-    clauses), the second a list of query terms as derived from the user
-    terms and used in the Xapian Query.
-
-Query.getxquery()
-    Return the Xapian query description as a Unicode string. Meaningful
-    only after executexx.
-
-Query.highlight(text, ishtml = 0, methods = object)
-    Will insert ,  tags around the match
-    areas in the input text and return the modified text. ``ishtml`` can
-    be set to indicate that the input text is HTML and that HTML special
-    characters should not be escaped. ``methods`` if set should be an
-    object with methods startMatch(i) and endMatch() which will be
-    called for each match and should return a begin and end tag
-
-Query.makedocabstract(doc, methods = object))
-    Create a snippets abstract for ``doc`` (a ``Doc`` object) by
-    selecting text around the match terms. If methods is set, will also
-    perform highlighting. See the highlight method.
-
-Query.\_\_iter\_\_() and Query.next()
-    So that things like ``for doc in
-                  query:`` will work.
-
-Query.arraysize
-    Default number of records processed by fetchmany (r/w).
-
-Query.rowcount
-    Number of records returned by the last execute.
-
-Query.rownumber
-    Next index to be fetched from results. Normally increments after
-    each fetchone() call, but can be set/reset before the call to effect
-    seeking (equivalent to using ``scroll()``). Starts at 0.
-
-A ``Doc`` object contains index data for a given document. The data is
-extracted from the index when searching, or set by the indexer program
-when updating. The Doc object has many attributes to be read or set by
-its user. It mostly matches the Rcl::Doc C++ object. Some of the
-attributes are predefined, but, especially when indexing, others can be
-set, the name of which will be processed as field names by the indexing
-configuration. Inputs can be specified as Unicode or strings. Outputs
-are Unicode objects. All dates are specified as Unix timestamps, printed
-as strings. Please refer to the ``rcldb/rcldoc.cpp`` C++ file for a full
-description of the predefined attributes. Here follows a short list.
-
--  ``url`` the document URL but see also ``getbinurl()``
-
--  ``ipath`` the document ``ipath`` for embedded documents.
-
--  ``fbytes, dbytes`` the document file and text sizes.
-
--  ``fmtime, dmtime`` the document file and document times.
-
--  ``xdocid`` the document Xapian document ID. This is useful if you
-   want to access the document through a direct Xapian operation.
-
--  ``mtype`` the document MIME type.
-
--  Fields stored by default: ``author``, ``filename``, ``keywords``,
-   ``recipient``
-
-At query time, only the fields that are defined as ``stored`` either by
-default or in the ``fields`` configuration file will be meaningful in
-the ``Doc`` object. The document processed text may be present or not,
-depending if the index stores the text at all, and if it does, on the
-``fetchtext`` query execute option. See also the ``rclextract`` module
-for accessing document contents.
-
-get(key), [] operator
-    Retrieve the named document attribute. You can also use
-    ``getattr(doc,
-                  key)`` or ``doc.key``.
-
-doc.key = value
-    Set the the named document attribute. You can also use
-    ``setattr(doc, key,
-                  value)``.
-
-getbinurl()
-    Retrieve the URL in byte array format (no transcoding), for use as
-    parameter to a system call.
-
-setbinurl(url)
-    Set the URL in byte array format (no transcoding).
-
-items()
-    Return a dictionary of doc object keys/values
-
-keys()
-    list of doc object keys (attribute names).
-
-A ``SearchData`` object allows building a query by combining clauses,
-for execution by ``Query.executesd()``. It can be used in replacement of
-the query language approach. The interface is going to change a little,
-so no detailed doc for now...
-
-addclause(type='and'\|'or'\|'excl'\|'phrase'\|'near'\|'sub',
-qstring=string, slack=0, field='', stemming=1, subSearch=SearchData)
-
-The rclextract module
-^^^^^^^^^^^^^^^^^^^^^
-
-Prior to RCL 1.25, index queries could not provide document content
-because it was never stored. RCL 1.25 and later usually store the
-document text, which can be optionally retrieved when running a query
-(see ``query.execute()`` above - the result is always plain text).
-
-The ``rclextract`` module can give access to the original document and
-to the document text content (if not stored by the index, or to access
-an HTML version of the text). Acessing the original document is
-particularly useful if it is embedded (e.g. an email attachment).
-
-You need to import the ``recoll`` module before the ``rclextract``
-module.
-
-Extractor(doc)
-    An ``Extractor`` object is built from a ``Doc`` object, output from
-    a query.
-
-Extractor.textextract(ipath)
-    Extract document defined by ipath and return a ``Doc`` object. The
-    ``doc.text`` field has the document text converted to either
-    text/plain or text/html according to ``doc.mimetype``. The typical
-    use would be as follows:
-
-    ::
-
-        from recoll import recoll, rclextract
-
-        qdoc = query.fetchone()
-        extractor = recoll.Extractor(qdoc)
-        doc = extractor.textextract(qdoc.ipath)
-        # use doc.text, e.g. for previewing
-
-    Passing ``qdoc.ipath`` to ``textextract()`` is redundant, but
-    reflects the fact that the ``Extractor`` object actually has the
-    capability to access the other entries in a compound document.
-
-Extractor.idoctofile(ipath, targetmtype, outfile='')
-    Extracts document into an output file, which can be given explicitly
-    or will be created as a temporary file to be deleted by the caller.
-    Typical use:
-
-    ::
-
-        from recoll import recoll, rclextract
-
-        qdoc = query.fetchone()
-        extractor = recoll.Extractor(qdoc)
-        filename = extractor.idoctofile(qdoc.ipath, qdoc.mimetype)
-
-    In all cases the output is a copy, even if the requested document is
-    a regular system file, which may be wasteful in some cases. If you
-    want to avoid this, you can test for a simple file document as
-    follows:
-
-    ::
-
-        not doc.ipath and (not "rclbes" in doc.keys() or doc["rclbes"] == "FS")
-
-Search API usage example
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-The following sample would query the index with a user language string.
-See the ``python/samples`` directory inside the RCL source for other
-examples. The ``recollgui`` subdirectory has a very embryonic GUI which
-demonstrates the highlighting and data extraction functions.
-
-::
-
-    #!/usr/bin/env python
-
-    from recoll import recoll
-
-    db = recoll.connect()
-    db.setAbstractParams(maxchars=80, contextwords=4)
-
-    query = db.query()
-    nres = query.execute("some user question")
-    print "Result count: ", nres
-    if nres > 5:
-        nres = 5
-    for i in range(nres):
-        doc = query.fetchone()
-        print "Result #%d" % (query.rownumber,)
-        for k in ("title", "size"):
-            print k, ":", getattr(doc, k).encode('utf-8')
-        abs = db.makeDocAbstract(doc, query).encode('utf-8')
-        print abs
-        print
-
-Creating Python external indexers
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The update API can be used to create an index from data which is not
-accessible to the regular RCL indexer, or structured to present
-difficulties to the RCL input handlers.
-
-An indexer created using this API will be have equivalent work to do as
-the the Recoll file system indexer: look for modified documents, extract
-their text, call the API for indexing it, take care of purging the index
-out of data from documents which do not exist in the document store any
-more.
-
-The data for such an external indexer should be stored in an index
-separate from any used by the RCL internal file system indexer. The
-reason is that the main document indexer purge pass (removal of deleted
-documents) would also remove all the documents belonging to the external
-indexer, as they were not seen during the filesystem walk. The main
-indexer documents would also probably be a problem for the external
-indexer own purge operation.
-
-While there would be ways to enable multiple foreign indexers to
-cooperate on a single index, it is just simpler to use separate ones,
-and use the multiple index access capabilities of the query interface,
-if needed.
-
-There are two parts in the update interface:
-
--  Methods inside the ``recoll`` module allow inserting data into the
-   index, to make it accessible by the normal query interface.
-
--  An interface based on scripts execution is defined to allow either
-   the GUI or the ``rclextract`` module to access original document data
-   for previewing or editing.
-
-Python update interface
-^^^^^^^^^^^^^^^^^^^^^^^
-
-The update methods are part of the ``recoll`` module described above.
-The connect() method is used with a ``writable=true`` parameter to
-obtain a writable ``Db`` object. The following ``Db`` object methods are
-then available.
-
-addOrUpdate(udi, doc, parent\_udi=None)
-    Add or update index data for a given document The ``
-                  
-                    udi`` string must define a unique id for the
-    document. It is an opaque interface element and not interpreted
-    inside Recoll. ``doc`` is a ``
-                      
-                        Doc`` object, created from the data to be
-    indexed (the main text should be in ``doc.text``). If ``
-                        
-                          parent_udi`` is set, this is a unique
-    identifier for the top-level container (e.g. for the filesystem
-    indexer, this would be the one which is an actual file).
-
-delete(udi)
-    Purge index from all data for ``udi``, and all documents (if any)
-    which have a matrching ``parent_udi``.
-
-needUpdate(udi, sig)
-    Test if the index needs to be updated for the document identified by
-    ``udi``. If this call is to be used, the ``doc.sig`` field should
-    contain a signature value when calling ``addOrUpdate()``. The
-    ``needUpdate()`` call then compares its parameter value with the
-    stored ``sig`` for ``udi``. ``sig`` is an opaque value, compared as
-    a string.
-
-    The filesystem indexer uses a concatenation of the decimal string
-    values for file size and update time, but a hash of the contents
-    could also be used.
-
-    As a side effect, if the return value is false (the index is up to
-    date), the call will set the existence flag for the document (and
-    any subdocument defined by its ``parent_udi``), so that a later
-    ``purge()`` call will preserve them).
-
-    The use of ``needUpdate()`` and ``purge()`` is optional, and the
-    indexer may use another method for checking the need to reindex or
-    to delete stale entries.
-
-purge()
-    Delete all documents that were not touched during the just finished
-    indexing pass (since open-for-write). These are the documents for
-    the needUpdate() call was not performed, indicating that they no
-    longer exist in the primary storage system.
-
-Query data access for external indexers (1.23)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-RCL has internal methods to access document data for its internal
-(filesystem) indexer. An external indexer needs to provide data access
-methods if it needs integration with the GUI (e.g. preview function), or
-support for the ``rclextract`` module.
-
-The index data and the access method are linked by the ``rclbes``
-(recoll backend storage) ``Doc`` field. You should set this to a short
-string value identifying your indexer (e.g. the filesystem indexer uses
-either "FS" or an empty value, the Web history indexer uses "BGL").
-
-The link is actually performed inside a ``backends`` configuration file
-(stored in the configuration directory). This defines commands to
-execute to access data from the specified indexer. Example, for the mbox
-indexing sample found in the Recoll source (which sets
-``rclbes="MBOX"``):
-
-::
-
-    [MBOX]
-              fetch = /path/to/recoll/src/python/samples/rclmbox.py fetch
-              makesig = path/to/recoll/src/python/samples/rclmbox.py makesig
-              
-
-``fetch`` and ``makesig`` define two commands to execute to respectively
-retrieve the document text and compute the document signature (the
-example implementation uses the same script with different first
-parameters to perform both operations).
-
-The scripts are called with three additional arguments: ``udi``,
-``url``, ``ipath``, stored with the document when it was indexed, and
-may use any or all to perform the requested operation. The caller
-expects the result data on ``stdout``.
-
-External indexer samples
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-The Recoll source tree has two samples of external indexers in the
-``src/python/samples`` directory. The more interesting one is
-``rclmbox.py`` which indexes a directory containing ``mbox`` folder
-files. It exercises most features in the update interface, and has a
-data access interface.
-
-See the comments inside the file for more information.
-
-Package compatibility with the previous version
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following code fragments can be used to ensure that code can run
-with both the old and the new API (as long as it does not use the new
-abilities of the new API of course).
-
-Adapting to the new package structure:
-
-::
-
-              
-                       try:
-                       from recoll import recoll
-                       from recoll import rclextract
-                       hasextract = True
-                       except:
-                       import recoll
-                       hasextract = False
-              
-            
-
-Adapting to the change of nature of the ``next`` ``Query`` member. The
-same test can be used to choose to use the ``scroll()`` method (new) or
-set the ``next`` value (old).
-
-::
-
-              
-                       rownum = query.next if type(query.next) == int else \
-                       query.rownumber
-              
-            
-
-Installation and configuration
-==============================
-
-Installing a binary copy
-------------------------
-
-RCL binary copies are always distributed as regular packages for your
-system. They can be obtained either through the system's normal software
-distribution framework (e.g. Debian/Ubuntu apt, FreeBSD ports, etc.), or
-from some type of "backports" repository providing versions newer than
-the standard ones, or found on the RCL WEB site in some cases. The most
-up-to-date information about Recoll packages can usually be found on the
-`Recoll WEB site downloads page `__
-
-There used to exist another form of binary install, as pre-compiled
-source trees, but these are just less convenient than the packages and
-don't exist any more.
-
-The package management tools will usually automatically deal with hard
-dependancies for packages obtained from a proper package repository. You
-will have to deal with them by hand for downloaded packages (for
-example, when ``dpkg`` complains about missing dependancies).
-
-In all cases, you will have to check or install `supporting
-applications <#RCL.INSTALL.EXTERNAL>`__ for the file types that you want
-to index beyond those that are natively processed by RCL (text, HTML,
-email files, and a few others).
-
-You should also maybe have a look at the `configuration
-section <#RCL.INSTALL.CONFIG>`__ (but this may not be necessary for a
-quick test with default parameters). Most parameters can be more
-conveniently set from the GUI interface.
-
-Supporting packages
--------------------
-
-    **Note**
-
-    The WIN installation of RCL is self-contained, and only needs Python
-    2.7 to be externally installed. WIN users can skip this section.
-
-RCL uses external applications to index some file types. You need to
-install them for the file types that you wish to have indexed (these are
-run-time optional dependencies. None is needed for building or running
-RCL except for indexing their specific file type).
-
-After an indexing pass, the commands that were found missing can be
-displayed from the ``recoll`` File menu. The list is stored in the
-``missing`` text file inside the configuration directory.
-
-A list of common file types which need external commands follows. Many
-of the handlers need the ``iconv`` command, which is not always listed
-as a dependancy.
-
-Please note that, due to the relatively dynamic nature of this
-information, the most up to date version is now kept on RCLAPPS along
-with links to the home pages or best source/patches pages, and misc
-tips. The list below is not updated often and may be quite stale.
-
-For many Linux distributions, most of the commands listed can be
-installed from the package repositories. However, the packages are
-sometimes outdated, or not the best version for RCL, so you should take
-a look at RCLAPPS if a file type is important to you.
-
-As of RCL release 1.14, a number of XML-based formats that were handled
-by ad hoc handler code now use the ``xsltproc`` command, which usually
-comes with libxslt. These are: abiword, fb2 (ebooks), kword, openoffice,
-svg.
-
-Now for the list:
-
--  Openoffice files need ``unzip`` and ``xsltproc``.
-
--  PDF files need ``pdftotext`` which is part of Poppler (usually comes
-   with the ``poppler-utils`` package). Avoid the original one from
-   Xpdf.
-
--  Postscript files need ``pstotext``. The original version has an issue
-   with shell character in file names, which is corrected in recent
-   packages. See RCLAPPS for more detail.
-
--  MS Word needs ``antiword``. It is also useful to have ``wvWare``
-   installed as it may be be used as a fallback for some files which
-   ``antiword`` does not handle.
-
--  MS Excel and PowerPoint are processed by internal ``Python``
-   handlers.
-
--  MS Open XML (docx) needs ``
-           xsltproc``.
-
--  Wordperfect files need ``wpd2html`` from the libwpd (or libwpd-tools
-   on Ubuntu) package.
-
--  RTF files need ``unrtf``, which, in its older versions, has much
-   trouble with non-western character sets. Many Linux distributions
-   carry outdated ``unrtf`` versions. Check RCLAPPS for details.
-
--  TeX files need ``untex`` or ``detex``. Check RCLAPPS for sources if
-   it's not packaged for your distribution.
-
--  dvi files need ``dvips``.
-
--  djvu files need ``djvutxt`` and ``djvused`` from the DjVuLibre
-   package.
-
--  Audio files: RCL releases 1.14 and later use a single Python handler
-   based on mutagen for all audio file types.
-
--  Pictures: RCL uses the Exiftool Perl package to extract tag
-   information. Most image file formats are supported. Note that there
-   may not be much interest in indexing the technical tags (image size,
-   aperture, etc.). This is only of interest if you store personal tags
-   or textual descriptions inside the image files.
-
--  chm: files in Microsoft help format need Python and the pychm module
-   (which needs chmlib).
-
--  ICS: up to RCL 1.13, iCalendar files need Python and the icalendar
-   module. icalendar is not needed for newer versions, which use
-   internal code.
-
--  Zip archives need Python (and the standard zipfile module).
-
--  Rar archives need Python, the rarfile Python module and the ``unrar``
-   utility.
-
--  Midi karaoke files need Python and the `Midi
-   module `__
-
--  Konqueror webarchive format with Python (uses the Tarfile module).
-
--  Mimehtml web archive format (support based on the email handler,
-   which introduces some mild weirdness, but still usable).
-
-Text, HTML, email folders, and Scribus files are processed internally.
-Lyx is used to index Lyx files. Many handlers need ``iconv`` and the
-standard ``sed`` and ``awk``.
-
-Building from source
---------------------
-
-Prerequisites
-~~~~~~~~~~~~~
-
-The following prerequisites are described in broad terms and not as
-specific package names (which will depend on the exact platform). The
-dependancies should be available as packages on most common Unix
-derivatives, and it should be quite uncommon that you would have to
-build one of them.
-
-The shopping list:
-
--  The ``autoconf``, ``automake`` and ``libtool`` triad. Only
-   ``autoconf`` is needed for RCL 1.21 and earlier.
-
--  C++ compiler. Recent versions require C++11 compatibility (1.23 and
-   later).
-
--  ``bison`` command (for RCL 1.21 and later).
-
--  ``xsltproc`` command. For building the documentation (for RCL 1.21
-   and later). This sometimes comes with the libxslt package. And also
-   the Docbook XML and style sheet files.
-
--  Development files for `Xapian core `__.
-
-       **Important**
-
-       If you are building Xapian for an older CPU (before Pentium 4 or
-       Athlon 64), you need to add the ``--disable-sse`` flag to the
-       configure command. Else all Xapian application will crash with an
-       ``illegal instruction`` error.
-
--  Development files for `Qt 4 or Qt
-   5 `__. RCL 1.15.9 was the last
-   version to support Qt 3. If you do not want to install or build the
-   Qt Webkit module, RCL has a configuration option to disable its use
-   (see further in the configuration section).
-
--  Development files for X11 and zlib.
-
--  Development files for Python (or use ``--disable-python-module``).
-
--  You may also need
-   `libiconv `__. On Linux
-   systems, the iconv interface is part of libc and you should not need
-   to do anything special.
-
-Check the `RCL download page `__
-for up to date version information.
-
-Building
-~~~~~~~~
-
-RCL has been built on Linux, FreeBSD, Mac OS X, and Solaris, most
-versions after 2005 should be ok, maybe some older ones too (Solaris 8
-is ok). If you build on another system, and need to modify things, `I
-would very much welcome patches `__.
-
-**Configure options:.**
-
--  ``--without-aspell`` will disable the code for phonetic matching of
-   search terms.
-
--  ``--with-fam`` or ``--with-inotify`` will enable the code for real
-   time indexing. Inotify support is enabled by default on recent Linux
-   systems.
-
--  ``--with-qzeitgeist`` will enable sending Zeitgeist events about the
-   visited search results, and needs the qzeitgeist package.
-
--  ``--disable-webkit`` is available from version 1.17 to implement the
-   result list with a Qt QTextBrowser instead of a WebKit widget if you
-   do not or can't depend on the latter.
-
--  ``--disable-idxthreads`` is available from version 1.19 to suppress
-   multithreading inside the indexing process. You can also use the
-   run-time configuration to restrict ``recollindex`` to using a single
-   thread, but the compile-time option may disable a few more unused
-   locks. This only applies to the use of multithreading for the core
-   index processing (data input). The RCL monitor mode always uses at
-   least two threads of execution.
-
--  ``--disable-python-module`` will avoid building the Python module.
-
--  ``--disable-xattr`` will prevent fetching data from file extended
-   attributes. Beyond a few standard attributes, fetching extended
-   attributes data can only be useful is some application stores data in
-   there, and also needs some simple configuration (see comments in the
-   ``fields`` configuration file).
-
--  ``--enable-camelcase`` will enable splitting camelCase words. This is
-   not enabled by default as it has the unfortunate side-effect of
-   making some phrase searches quite confusing: ie, ``"MySQL manual"``
-   would be matched by ``"MySQL manual"`` and ``"my sql manual"`` but
-   not ``"mysql
-                 manual"`` (only inside phrase searches).
-
--  ``--with-file-command`` Specify the version of the 'file' command to
-   use (ie: --with-file-command=/usr/local/bin/file). Can be useful to
-   enable the gnu version on systems where the native one is bad.
-
--  ``--disable-qtgui`` Disable the Qt interface. Will allow building the
-   indexer and the command line search program in absence of a Qt
-   environment.
-
--  ``--disable-x11mon`` Disable X11 connection monitoring inside
-   recollindex. Together with --disable-qtgui, this allows building
-   recoll without Qt and X11.
-
--  ``--disable-userdoc`` will avoid building the user manual. This
-   avoids having to install the Docbook XML/XSL files and the TeX
-   toolchain used for translating the manual to PDF.
-
--  ``--disable-pic`` (RCL versions up to 1.21 only) will compile RCL
-   with position-dependant code. This is incompatible with building the
-   KIO or the Python or PHP extensions, but might yield very marginally
-   faster code.
-
--  Of course the usual autoconf ``configure`` options, like ``--prefix``
-   apply.
-
-Normal procedure (for source extracted from a tar distribution):
-
-::
-
-              cd recoll-xxx
-              ./configure
-              make
-              (practices usual hardship-repelling invocations)
-            
-
-When building from source cloned from the git repository, you also need
-to install autoconf, automake, and libtool and you must execute ``sh
-        autogen.sh`` in the top source directory before running
-``configure``.
-
-Installing
-~~~~~~~~~~
-
-Use ``make install`` in the root of the source tree. This will copy the
-commands to ``prefix/bin`` and the sample configuration files, scripts
-and other shared data to ``prefix/share/recoll``.
-
-Python API package
-~~~~~~~~~~~~~~~~~~
-
-The Python interface can be found in the source tree, under the
-``python/recoll`` directory.
-
-As of RCL 1.19, the module can be compiled for Python3.
-
-The normal RCL build procedure (see above) installs the API package for
-the default system version (python) along with the main code. The
-package for other Python versions (e.g. python3 if the system default is
-python2) must be explicitely built and installed.
-
-The ``python/recoll/`` directory contains the usual ``setup.py``. After
-configuring and building the main RCL code, you can use the script to
-build and install the Python module:
-
-::
-
-              cd recoll-xxx/python/recoll
-              pythonX setup.py build
-              sudo pythonX setup.py install
-            
-
-Building on Solaris
-~~~~~~~~~~~~~~~~~~~
-
-We did not test building the GUI on Solaris for recent versions. You
-will need at least Qt 4.4. There are some hints on `an old web site
-page `__, they may still be
-valid.
-
-Someone did test the 1.19 indexer and Python module build, they do work,
-with a few minor glitches. Be sure to use GNU ``make`` and ``install``.
-
-Configuration overview
-----------------------
-
-Most of the parameters specific to the ``recoll`` GUI are set through
-the Preferences menu and stored in the standard Qt place
-(``$HOME/.config/Recoll.org/recoll.conf``). You probably do not want to
-edit this by hand.
-
-RCL indexing options are set inside text configuration files located in
-a configuration directory. There can be several such directories, each
-of which defines the parameters for one index.
-
-The configuration files can be edited by hand or through the Index
-configuration dialog (Preferences menu). The GUI tool will try to
-respect your formatting and comments as much as possible, so it is quite
-possible to use both approaches on the same configuration.
-
-The most accurate documentation for the configuration parameters is
-given by comments inside the default files, and we will just give a
-general overview here.
-
-For each index, there are at least two sets of configuration files.
-System-wide configuration files are kept in a directory named like
-``/usr/share/recoll/examples``, and define default values, shared by all
-indexes. For each index, a parallel set of files defines the customized
-parameters.
-
-The default location of the customized configuration is the ``.recoll``
-directory in your home. Most people will only use this directory.
-
-This location can be changed, or others can be added with the
-RECOLL\_CONFDIR environment variable or the ``-c`` option parameter to
-``recoll`` and ``recollindex``.
-
-In addition (as of RCL version 1.19.7), it is possible to specify two
-additional configuration directories which will be stacked before and
-after the user configuration directory. These are defined by the
-RECOLL\_CONFTOP and RECOLL\_CONFMID environment variables. Values from
-configuration files inside the top directory will override user ones,
-values from configuration files inside the middle directory will
-override system ones and be overriden by user ones. These two variables
-may be of use to applications which augment RCL functionality, and need
-to add configuration data without disturbing the user's files. Please
-note that the two, currently single, values will probably be interpreted
-as colon-separated lists in the future: do not use colon characters
-inside the directory paths.
-
-If the ``.recoll`` directory does not exist when ``recoll`` or
-``recollindex`` are started, it will be created with a set of empty
-configuration files. ``recoll`` will give you a chance to edit the
-configuration file before starting indexing. ``recollindex`` will
-proceed immediately. To avoid mistakes, the automatic directory creation
-will only occur for the default location, not if ``-c`` or
-RECOLL\_CONFDIR were used (in the latter cases, you will have to create
-the directory).
-
-All configuration files share the same format. For example, a short
-extract of the main configuration file might look as follows:
-
-::
-
-            # Space-separated list of files and directories to index.
-            topdirs =  ~/docs /usr/share/doc
-
-            [~/somedirectory-with-utf8-txt-files]
-            defaultcharset = utf-8
-          
-
-There are three kinds of lines:
-
--  Comment (starts with *#*) or empty.
-
--  Parameter affectation (*name = value*).
-
--  Section definition ([*somedirname*]).
-
-Long lines can be broken by ending each incomplete part with a backslash
-(``\``).
-
-Depending on the type of configuration file, section definitions either
-separate groups of parameters or allow redefining some parameters for a
-directory sub-tree. They stay in effect until another section
-definition, or the end of file, is encountered. Some of the parameters
-used for indexing are looked up hierarchically from the current
-directory location upwards. Not all parameters can be meaningfully
-redefined, this is specified for each in the next section.
-
-    **Important**
-
-    Global parameters *must not* be defined in a directory subsection,
-    else they will not be found at all by the RCL code, which looks for
-    them at the top level (e.g. ``skippedPaths``).
-
-When found at the beginning of a file path, the tilde character (~) is
-expanded to the name of the user's home directory, as a shell would do.
-
-Some parameters are lists of strings. White space is used for
-separation. List elements with embedded spaces can be quoted using
-double-quotes. Double quotes inside these elements can be escaped with a
-backslash.
-
-No value inside a configuration file can contain a newline character.
-Long lines can be continued by escaping the physical newline with
-backslash, even inside quoted strings.
-
-::
-
-            astringlist =  "some string \
-            with spaces"
-            thesame = "some string with spaces"        
-          
-
-Parameters which are not part of string lists can't be quoted, and
-leading and trailing space characters are stripped before the value is
-used.
-
-**Encoding issues.**
-
-Most of the configuration parameters are plain ASCII. Two particular
-sets of values may cause encoding issues:
-
--  File path parameters may contain non-ascii characters and should use
-   the exact same byte values as found in the file system directory.
-   Usually, this means that the configuration file should use the system
-   default locale encoding.
-
--  The unac\_except\_trans parameter should be encoded in UTF-8. If your
-   system locale is not UTF-8, and you need to also specify non-ascii
-   file paths, this poses a difficulty because common text editors
-   cannot handle multiple encodings in a single file. In this relatively
-   unlikely case, you can edit the configuration file as two separate
-   text files with appropriate encodings, and concatenate them to create
-   the complete configuration.
-
-Environment variables
-~~~~~~~~~~~~~~~~~~~~~
-
-``RECOLL_CONFDIR``
-    Defines the main configuration directory.
-
-``RECOLL_TMPDIR, TMPDIR``
-    Locations for temporary files, in this order of priority. The
-    default if none of these is set is to use ``/tmp``. Big temporary
-    files may be created during indexing, mostly for decompressing, and
-    also for processing, e.g. email attachments.
-
-``RECOLL_CONFTOP, RECOLL_CONFMID``
-    Allow adding configuration directories with priorities below and
-    above the user directory (see above the Configuration overview
-    section for details).
-
-``RECOLL_EXTRA_DBS, RECOLL_ACTIVE_EXTRA_DBS``
-    Help for setting up external indexes. See `this
-    paragraph <#RCL.SEARCH.GUI.MULTIDB>`__ for explanations.
-
-``RECOLL_DATADIR``
-    Defines replacement for the default location of Recoll data files,
-    normally found in, e.g., ``/usr/share/recoll``).
-
-``RECOLL_FILTERSDIR``
-    Defines replacement for the default location of Recoll filters,
-    normally found in, e.g., ``/usr/share/recoll/filters``).
-
-``ASPELL_PROG``
-    ``aspell`` program to use for creating the spelling dictionary. The
-    result has to be compatible with the ``libaspell`` which RCL is
-    using.
-
-``VARNAME``
-    Blabla
-
-Recoll main configuration file, recoll.conf
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Parameters affecting what documents we index
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-``topdirs``
-    Space-separated list of files or directories to recursively index.
-    Default to ~ (indexes $HOME). You can use symbolic links in the
-    list, they will be followed, independantly of the value of the
-    followLinks variable.
-
-``monitordirs``
-    Space-separated list of files or directories to monitor for updates.
-    When running the real-time indexer, this allows monitoring only a
-    subset of the whole indexed area. The elements must be included in
-    the tree defined by the 'topdirs' members.
-
-``skippedNames``
-    Files and directories which should be ignored. White space separated
-    list of wildcard patterns (simple ones, not paths, must contain no /
-    ), which will be tested against file and directory names. The list
-    in the default configuration does not exclude hidden directories
-    (names beginning with a dot), which means that it may index quite a
-    few things that you do not want. On the other hand, email user
-    agents like Thunderbird usually store messages in hidden
-    directories, and you probably want this indexed. One possible
-    solution is to have ".\*" in "skippedNames", and add things like
-    "~/.thunderbird" "~/.evolution" to "topdirs". Not even the file
-    names are indexed for patterns in this list, see the
-    "noContentSuffixes" variable for an alternative approach which
-    indexes the file names. Can be redefined for any subtree.
-
-``skippedNames-``
-    List of name endings to remove from the default skippedNames list.
-
-``skippedNames+``
-    List of name endings to add to the default skippedNames list.
-
-``noContentSuffixes``
-    List of name endings (not necessarily dot-separated suffixes) for
-    which we don't try MIME type identification, and don't uncompress or
-    index content. Only the names will be indexed. This complements the
-    now obsoleted recoll\_noindex list from the mimemap file, which will
-    go away in a future release (the move from mimemap to recoll.conf
-    allows editing the list through the GUI). This is different from
-    skippedNames because these are name ending matches only (not
-    wildcard patterns), and the file name itself gets indexed normally.
-    This can be redefined for subdirectories.
-
-``noContentSuffixes-``
-    List of name endings to remove from the default noContentSuffixes
-    list.
-
-``noContentSuffixes+``
-    List of name endings to add to the default noContentSuffixes list.
-
-``skippedPaths``
-    Absolute paths we should not go into. Space-separated list of
-    wildcard expressions for absolute filesystem paths. Must be defined
-    at the top level of the configuration file, not in a subsection. Can
-    contain files and directories. The database and configuration
-    directories will automatically be added. The expressions are matched
-    using 'fnmatch(3)' with the FNM\_PATHNAME flag set by default. This
-    means that '/' characters must be matched explicitely. You can set
-    'skippedPathsFnmPathname' to 0 to disable the use of FNM\_PATHNAME
-    (meaning that '/\*/dir3' will match '/dir1/dir2/dir3'). The default
-    value contains the usual mount point for removable media to remind
-    you that it is a bad idea to have Recoll work on these (esp. with
-    the monitor: media gets indexed on mount, all data gets erased on
-    unmount). Explicitely adding '/media/xxx' to the 'topdirs' variable
-    will override this.
-
-``skippedPathsFnmPathname``
-    Set to 0 to override use of FNM\_PATHNAME for matching skipped
-    paths.
-
-``nowalkfn``
-    File name which will cause its parent directory to be skipped. Any
-    directory containing a file with this name will be skipped as if it
-    was part of the skippedPaths list. Ex: .recoll-noindex
-
-``daemSkippedPaths``
-    skippedPaths equivalent specific to real time indexing. This enables
-    having parts of the tree which are initially indexed but not
-    monitored. If daemSkippedPaths is not set, the daemon uses
-    skippedPaths.
-
-``zipUseSkippedNames``
-    Use skippedNames inside Zip archives. Fetched directly by the rclzip
-    handler. Skip the patterns defined by skippedNames inside Zip
-    archives. Can be redefined for subdirectories. See
-    https://www.lesbonscomptes.com/recoll/faqsandhowtos/FilteringOutZipArchiveMembers.html
-
-``zipSkippedNames``
-    Space-separated list of wildcard expressions for names that should
-    be ignored inside zip archives. This is used directly by the zip
-    handler. If zipUseSkippedNames is not set, zipSkippedNames defines
-    the patterns to be skipped inside archives. If zipUseSkippedNames is
-    set, the two lists are concatenated and used. Can be redefined for
-    subdirectories. See
-    https://www.lesbonscomptes.com/recoll/faqsandhowtos/FilteringOutZipArchiveMembers.html
-
-``followLinks``
-    Follow symbolic links during indexing. The default is to ignore
-    symbolic links to avoid multiple indexing of linked files. No effort
-    is made to avoid duplication when this option is set to true. This
-    option can be set individually for each of the 'topdirs' members by
-    using sections. It can not be changed below the 'topdirs' level.
-    Links in the 'topdirs' list itself are always followed.
-
-``indexedmimetypes``
-    Restrictive list of indexed mime types. Normally not set (in which
-    case all supported types are indexed). If it is set, only the types
-    from the list will have their contents indexed. The names will be
-    indexed anyway if indexallfilenames is set (default). MIME type
-    names should be taken from the mimemap file (the values may be
-    different from xdg-mime or file -i output in some cases). Can be
-    redefined for subtrees.
-
-``excludedmimetypes``
-    List of excluded MIME types. Lets you exclude some types from
-    indexing. MIME type names should be taken from the mimemap file (the
-    values may be different from xdg-mime or file -i output in some
-    cases) Can be redefined for subtrees.
-
-``nomd5types``
-    Don't compute md5 for these types. md5 checksums are used only for
-    deduplicating results, and can be very expensive to compute on
-    multimedia or other big files. This list lets you turn off md5
-    computation for selected types. It is global (no redefinition for
-    subtrees). At the moment, it only has an effect for external
-    handlers (exec and execm). The file types can be specified by
-    listing either MIME types (e.g. audio/mpeg) or handler names (e.g.
-    rclaudio).
-
-``compressedfilemaxkbs``
-    Size limit for compressed files. We need to decompress these in a
-    temporary directory for identification, which can be wasteful in
-    some cases. Limit the waste. Negative means no limit. 0 results in
-    no processing of any compressed file. Default 50 MB.
-
-``textfilemaxmbs``
-    Size limit for text files. Mostly for skipping monster logs. Default
-    20 MB.
-
-``indexallfilenames``
-    Index the file names of unprocessed files Index the names of files
-    the contents of which we don't index because of an excluded or
-    unsupported MIME type.
-
-``usesystemfilecommand``
-    Use a system command for file MIME type guessing as a final step in
-    file type identification This is generally useful, but will usually
-    cause the indexing of many bogus 'text' files. See
-    'systemfilecommand' for the command used.
-
-``systemfilecommand``
-    Command used to guess MIME types if the internal methods fails This
-    should be a "file -i" workalike. The file path will be added as a
-    last parameter to the command line. 'xdg-mime' works better than the
-    traditional 'file' command, and is now the configured default (with
-    a hard-coded fallback to 'file')
-
-``processwebqueue``
-    Decide if we process the Web queue. The queue is a directory where
-    the Recoll Web browser plugins create the copies of visited pages.
-
-``textfilepagekbs``
-    Page size for text files. If this is set, text/plain files will be
-    divided into documents of approximately this size. Will reduce
-    memory usage at index time and help with loading data in the preview
-    window at query time. Particularly useful with very big files, such
-    as application or system logs. Also see textfilemaxmbs and
-    compressedfilemaxkbs.
-
-``membermaxkbs``
-    Size limit for archive members. This is passed to the filters in the
-    environment as RECOLL\_FILTER\_MAXMEMBERKB.
-
-Parameters affecting how we generate terms and organize the index
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-``indexStripChars``
-    Decide if we store character case and diacritics in the index. If we
-    do, searches sensitive to case and diacritics can be performed, but
-    the index will be bigger, and some marginal weirdness may sometimes
-    occur. The default is a stripped index. When using multiple indexes
-    for a search, this parameter must be defined identically for all.
-    Changing the value implies an index reset.
-
-``indexStoreDocText``
-    Decide if we store the documents' text content in the index. Storing
-    the text allows extracting snippets from it at query time, instead
-    of building them from index position data. Newer Xapian index
-    formats have rendered our use of positions list unacceptably slow in
-    some cases. The last Xapian index format with good performance for
-    the old method is Chert, which is default for 1.2, still supported
-    but not default in 1.4 and will be dropped in 1.6. The stored
-    document text is translated from its original format to UTF-8 plain
-    text, but not stripped of upper-case, diacritics, or punctuation
-    signs. Storing it increases the index size by 10-20% typically, but
-    also allows for nicer snippets, so it may be worth enabling it even
-    if not strictly needed for performance if you can afford the space.
-    The variable only has an effect when creating an index, meaning that
-    the xapiandb directory must not exist yet. Its exact effect depends
-    on the Xapian version. For Xapian 1.4, if the variable is set to 0,
-    the Chert format will be used, and the text will not be stored. If
-    the variable is 1, Glass will be used, and the text stored. For
-    Xapian 1.2, and for versions after 1.5 and newer, the index format
-    is always the default, but the variable controls if the text is
-    stored or not, and the abstract generation method. With Xapian 1.5
-    and later, and the variable set to 0, abstract generation may be
-    very slow, but this setting may still be useful to save space if you
-    do not use abstract generation at all.
-
-``nonumbers``
-    Decides if terms will be generated for numbers. For example "123",
-    "1.5e6", 192.168.1.4, would not be indexed if nonumbers is set
-    ("value123" would still be). Numbers are often quite interesting to
-    search for, and this should probably not be set except for special
-    situations, ie, scientific documents with huge amounts of numbers in
-    them, where setting nonumbers will reduce the index size. This can
-    only be set for a whole index, not for a subtree.
-
-``dehyphenate``
-    Determines if we index 'coworker' also when the input is
-    'co-worker'. This is new in version 1.22, and on by default. Setting
-    the variable to off allows restoring the previous behaviour.
-
-``backslashasletter``
-    Process backslash as normal letter This may make sense for people
-    wanting to index TeX commands as such but is not of much general
-    use.
-
-``maxtermlength``
-    Maximum term length. Words longer than this will be discarded. The
-    default is 40 and used to be hard-coded, but it can now be adjusted.
-    You need an index reset if you change the value.
-
-``nocjk``
-    Decides if specific East Asian (Chinese Korean Japanese)
-    characters/word splitting is turned off. This will save a small
-    amount of CPU if you have no CJK documents. If your document base
-    does include such text but you are not interested in searching it,
-    setting nocjk may be a significant time and space saver.
-
-``cjkngramlen``
-    This lets you adjust the size of n-grams used for indexing CJK text.
-    The default value of 2 is probably appropriate in most cases. A
-    value of 3 would allow more precision and efficiency on longer
-    words, but the index will be approximately twice as large.
-
-``indexstemminglanguages``
-    Languages for which to create stemming expansion data. Stemmer names
-    can be found by executing 'recollindex -l', or this can also be set
-    from a list in the GUI.
-
-``defaultcharset``
-    Default character set. This is used for files which do not contain a
-    character set definition (e.g.: text/plain). Values found inside
-    files, e.g. a 'charset' tag in HTML documents, will override it. If
-    this is not set, the default character set is the one defined by the
-    NLS environment ($LC\_ALL, $LC\_CTYPE, $LANG), or ultimately
-    iso-8859-1 (cp-1252 in fact). If for some reason you want a general
-    default which does not match your LANG and is not 8859-1, use this
-    variable. This can be redefined for any sub-directory.
-
-``unac_except_trans``
-    A list of characters, encoded in UTF-8, which should be handled
-    specially when converting text to unaccented lowercase. For example,
-    in Swedish, the letter a with diaeresis has full alphabet
-    citizenship and should not be turned into an a. Each element in the
-    space-separated list has the special character as first element and
-    the translation following. The handling of both the lowercase and
-    upper-case versions of a character should be specified, as
-    appartenance to the list will turn-off both standard accent and case
-    processing. The value is global and affects both indexing and
-    querying. Examples: Swedish: unac\_except\_trans = ää Ää öö Öö üü Üü
-    ßss œoe Œoe æae Æae ffff fifi flfl åå Åå . German: unac\_except\_trans
-    = ää Ää öö Öö üü Üü ßss œoe Œoe æae Æae ffff fifi flfl In French, you
-    probably want to decompose oe and ae and nobody would type a German
-    ß unac\_except\_trans = ßss œoe Œoe æae Æae ffff fifi flfl . The
-    default for all until someone protests follows. These decompositions
-    are not performed by unac, but it is unlikely that someone would
-    type the composed forms in a search. unac\_except\_trans = ßss œoe
-    Œoe æae Æae ffff fifi flfl
-
-``maildefcharset``
-    Overrides the default character set for email messages which don't
-    specify one. This is mainly useful for readpst (libpst) dumps, which
-    are utf-8 but do not say so.
-
-``localfields``
-    Set fields on all files (usually of a specific fs area). Syntax is
-    the usual: name = value ; attr1 = val1 ; [...] value is empty so
-    this needs an initial semi-colon. This is useful, e.g., for setting
-    the rclaptg field for application selection inside mimeview.
-
-``testmodifusemtime``
-    Use mtime instead of ctime to test if a file has been modified. The
-    time is used in addition to the size, which is always used. Setting
-    this can reduce re-indexing on systems where extended attributes are
-    used (by some other application), but not indexed, because changing
-    extended attributes only affects ctime. Notes: - This may prevent
-    detection of change in some marginal file rename cases (the target
-    would need to have the same size and mtime). - You should probably
-    also set noxattrfields to 1 in this case, except if you still prefer
-    to perform xattr indexing, for example if the local file update
-    pattern makes it of value (as in general, there is a risk for pure
-    extended attributes updates without file modification to go
-    undetected). Perform a full index reset after changing this.
-
-``noxattrfields``
-    Disable extended attributes conversion to metadata fields. This
-    probably needs to be set if testmodifusemtime is set.
-
-``metadatacmds``
-    Define commands to gather external metadata, e.g. tmsu tags. There
-    can be several entries, separated by semi-colons, each defining
-    which field name the data goes into and the command to use. Don't
-    forget the initial semi-colon. All the field names must be
-    different. You can use aliases in the "field" file if necessary. As
-    a not too pretty hack conceded to convenience, any field name
-    beginning with "rclmulti" will be taken as an indication that the
-    command returns multiple field values inside a text blob formatted
-    as a recoll configuration file ("fieldname = fieldvalue" lines). The
-    rclmultixx name will be ignored, and field names and values will be
-    parsed from the data. Example: metadatacmds = ; tags = tmsu tags %f;
-    rclmulti1 = cmdOutputsConf %f
-
-Parameters affecting where and how we store things
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-``cachedir``
-    Top directory for Recoll data. Recoll data directories are normally
-    located relative to the configuration directory (e.g.
-    ~/.recoll/xapiandb, ~/.recoll/mboxcache). If 'cachedir' is set, the
-    directories are stored under the specified value instead (e.g. if
-    cachedir is ~/.cache/recoll, the default dbdir would be
-    ~/.cache/recoll/xapiandb). This affects dbdir, webcachedir,
-    mboxcachedir, aspellDicDir, which can still be individually
-    specified to override cachedir. Note that if you have multiple
-    configurations, each must have a different cachedir, there is no
-    automatic computation of a subpath under cachedir.
-
-``maxfsoccuppc``
-    Maximum file system occupation over which we stop indexing. The
-    value is a percentage, corresponding to what the "Capacity" df
-    output column shows. The default value is 0, meaning no checking.
-
-``dbdir``
-    Xapian database directory location. This will be created on first
-    indexing. If the value is not an absolute path, it will be
-    interpreted as relative to cachedir if set, or the configuration
-    directory (-c argument or $RECOLL\_CONFDIR). If nothing is
-    specified, the default is then ~/.recoll/xapiandb/
-
-``idxstatusfile``
-    Name of the scratch file where the indexer process updates its
-    status. Default: idxstatus.txt inside the configuration directory.
-
-``mboxcachedir``
-    Directory location for storing mbox message offsets cache files.
-    This is normally 'mboxcache' under cachedir if set, or else under
-    the configuration directory, but it may be useful to share a
-    directory between different configurations.
-
-``mboxcacheminmbs``
-    Minimum mbox file size over which we cache the offsets. There is
-    really no sense in caching offsets for small files. The default is 5
-    MB.
-
-``webcachedir``
-    Directory where we store the archived web pages. This is only used
-    by the web history indexing code Default: cachedir/webcache if
-    cachedir is set, else $RECOLL\_CONFDIR/webcache
-
-``webcachemaxmbs``
-    Maximum size in MB of the Web archive. This is only used by the web
-    history indexing code. Default: 40 MB. Reducing the size will not
-    physically truncate the file.
-
-``webqueuedir``
-    The path to the Web indexing queue. This used to be hard-coded in
-    the old plugin as ~/.recollweb/ToIndex so there would be no need or
-    possibility to change it, but the WebExtensions plugin now downloads
-    the files to the user Downloads directory, and a script moves them
-    to webqueuedir. The script reads this value from the config so it
-    has become possible to change it.
-
-``webdownloadsdir``
-    The path to browser downloads directory. This is where the new
-    browser add-on extension has to create the files. They are then
-    moved by a script to webqueuedir.
-
-``aspellDicDir``
-    Aspell dictionary storage directory location. The aspell dictionary
-    (aspdict.(lang).rws) is normally stored in the directory specified
-    by cachedir if set, or under the configuration directory.
-
-``filtersdir``
-    Directory location for executable input handlers. If
-    RECOLL\_FILTERSDIR is set in the environment, we use it instead.
-    Defaults to $prefix/share/recoll/filters. Can be redefined for
-    subdirectories.
-
-``iconsdir``
-    Directory location for icons. The only reason to change this would
-    be if you want to change the icons displayed in the result list.
-    Defaults to $prefix/share/recoll/images
-
-Parameters affecting indexing performance and resource usage
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-``idxflushmb``
-    Threshold (megabytes of new data) where we flush from memory to disk
-    index. Setting this allows some control over memory usage by the
-    indexer process. A value of 0 means no explicit flushing, which lets
-    Xapian perform its own thing, meaning flushing every
-    $XAPIAN\_FLUSH\_THRESHOLD documents created, modified or deleted: as
-    memory usage depends on average document size, not only document
-    count, the Xapian approach is is not very useful, and you should let
-    Recoll manage the flushes. The program compiled value is 0. The
-    configured default value (from this file) is now 50 MB, and should
-    be ok in many cases. You can set it as low as 10 to conserve memory,
-    but if you are looking for maximum speed, you may want to experiment
-    with values between 20 and 200. In my experience, values beyond this
-    are always counterproductive. If you find otherwise, please drop me
-    a note.
-
-``filtermaxseconds``
-    Maximum external filter execution time in seconds. Default 1200
-    (20mn). Set to 0 for no limit. This is mainly to avoid infinite
-    loops in postscript files (loop.ps)
-
-``filtermaxmbytes``
-    Maximum virtual memory space for filter processes
-    (setrlimit(RLIMIT\_AS)), in megabytes. Note that this includes any
-    mapped libs (there is no reliable Linux way to limit the data space
-    only), so we need to be a bit generous here. Anything over 2000 will
-    be ignored on 32 bits machines.
-
-``thrQSizes``
-    Stage input queues configuration. There are three internal queues in
-    the indexing pipeline stages (file data extraction, terms
-    generation, index update). This parameter defines the queue depths
-    for each stage (three integer values). If a value of -1 is given for
-    a given stage, no queue is used, and the thread will go on
-    performing the next stage. In practise, deep queues have not been
-    shown to increase performance. Default: a value of 0 for the first
-    queue tells Recoll to perform autoconfiguration based on the
-    detected number of CPUs (no need for the two other values in this
-    case). Use thrQSizes = -1 -1 -1 to disable multithreading entirely.
-
-``thrTCounts``
-    Number of threads used for each indexing stage. The three stages
-    are: file data extraction, terms generation, index update). The use
-    of the counts is also controlled by some special values in
-    thrQSizes: if the first queue depth is 0, all counts are ignored
-    (autoconfigured); if a value of -1 is used for a queue depth, the
-    corresponding thread count is ignored. It makes no sense to use a
-    value other than 1 for the last stage because updating the Xapian
-    index is necessarily single-threaded (and protected by a mutex).
-
-Miscellaneous parameters
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-``loglevel``
-    Log file verbosity 1-6. A value of 2 will print only errors and
-    warnings. 3 will print information like document updates, 4 is quite
-    verbose and 6 very verbose.
-
-``logfilename``
-    Log file destination. Use 'stderr' (default) to write to the
-    console.
-
-``idxloglevel``
-    Override loglevel for the indexer.
-
-``idxlogfilename``
-    Override logfilename for the indexer.
-
-``daemloglevel``
-    Override loglevel for the indexer in real time mode. The default is
-    to use the idx... values if set, else the log... values.
-
-``daemlogfilename``
-    Override logfilename for the indexer in real time mode. The default
-    is to use the idx... values if set, else the log... values.
-
-``orgidxconfdir``
-    Original location of the configuration directory. This is used
-    exclusively for movable datasets. Locating the configuration
-    directory inside the directory tree makes it possible to provide
-    automatic query time path translations once the data set has moved
-    (for example, because it has been mounted on another location).
-
-``curidxconfdir``
-    Current location of the configuration directory. Complement
-    orgidxconfdir for movable datasets. This should be used if the
-    configuration directory has been copied from the dataset to another
-    location, either because the dataset is readonly and an r/w copy is
-    desired, or for performance reasons. This records the original moved
-    location before copy, to allow path translation computations. For
-    example if a dataset originally indexed as '/home/me/mydata/config'
-    has been mounted to '/media/me/mydata', and the GUI is running from
-    a copied configuration, orgidxconfdir would be
-    '/home/me/mydata/config', and curidxconfdir (as set in the copied
-    configuration) would be '/media/me/mydata/config'.
-
-``idxrundir``
-    Indexing process current directory. The input handlers sometimes
-    leave temporary files in the current directory, so it makes sense to
-    have recollindex chdir to some temporary directory. If the value is
-    empty, the current directory is not changed. If the value is
-    (literal) tmp, we use the temporary directory as set by the
-    environment (RECOLL\_TMPDIR else TMPDIR else /tmp). If the value is
-    an absolute path to a directory, we go there.
-
-``checkneedretryindexscript``
-    Script used to heuristically check if we need to retry indexing
-    files which previously failed. The default script checks the
-    modified dates on /usr/bin and /usr/local/bin. A relative path will
-    be looked up in the filters dirs, then in the path. Use an absolute
-    path to do otherwise.
-
-``recollhelperpath``
-    Additional places to search for helper executables. This is only
-    used on Windows for now.
-
-``idxabsmlen``
-    Length of abstracts we store while indexing. Recoll stores an
-    abstract for each indexed file. The text can come from an actual
-    'abstract' section in the document or will just be the beginning of
-    the document. It is stored in the index so that it can be displayed
-    inside the result lists without decoding the original file. The
-    idxabsmlen parameter defines the size of the stored abstract. The
-    default value is 250 bytes. The search interface gives you the
-    choice to display this stored text or a synthetic abstract built by
-    extracting text around the search terms. If you always prefer the
-    synthetic abstract, you can reduce this value and save a little
-    space.
-
-``idxmetastoredlen``
-    Truncation length of stored metadata fields. This does not affect
-    indexing (the whole field is processed anyway), just the amount of
-    data stored in the index for the purpose of displaying fields inside
-    result lists or previews. The default value is 150 bytes which may
-    be too low if you have custom fields.
-
-``idxtexttruncatelen``
-    Truncation length for all document texts. Only index the beginning
-    of documents. This is not recommended except if you are sure that
-    the interesting keywords are at the top and have severe disk space
-    issues.
-
-``aspellLanguage``
-    Language definitions to use when creating the aspell dictionary. The
-    value must match a set of aspell language definition files. You can
-    type "aspell dicts" to see a list The default if this is not set is
-    to use the NLS environment to guess the value.
-
-``aspellAddCreateParam``
-    Additional option and parameter to aspell dictionary creation
-    command. Some aspell packages may need an additional option (e.g. on
-    Debian Jessie: --local-data-dir=/usr/lib/aspell). See Debian bug
-    772415.
-
-``aspellKeepStderr``
-    Set this to have a look at aspell dictionary creation errors. There
-    are always many, so this is mostly for debugging.
-
-``noaspell``
-    Disable aspell use. The aspell dictionary generation takes time, and
-    some combinations of aspell version, language, and local terms,
-    result in aspell crashing, so it sometimes makes sense to just
-    disable the thing.
-
-``monauxinterval``
-    Auxiliary database update interval. The real time indexer only
-    updates the auxiliary databases (stemdb, aspell) periodically,
-    because it would be too costly to do it for every document change.
-    The default period is one hour.
-
-``monixinterval``
-    Minimum interval (seconds) between processings of the indexing
-    queue. The real time indexer does not process each event when it
-    comes in, but lets the queue accumulate, to diminish overhead and to
-    aggregate multiple events affecting the same file. Default 30 S.
-
-``mondelaypatterns``
-    Timing parameters for the real time indexing. Definitions for files
-    which get a longer delay before reindexing is allowed. This is for
-    fast-changing files, that should only be reindexed once in a while.
-    A list of wildcardPattern:seconds pairs. The patterns are matched
-    with fnmatch(pattern, path, 0) You can quote entries containing
-    white space with double quotes (quote the whole entry, not the
-    pattern). The default is empty. Example: mondelaypatterns =
-    \*.log:20 "\*with spaces.\*:30"
-
-``monioniceclass``
-    ionice class for the real time indexing process On platforms where
-    this is supported. The default value is 3.
-
-``monioniceclassdata``
-    ionice class parameter for the real time indexing process. On
-    platforms where this is supported. The default is empty.
-
-Query-time parameters (no impact on the index)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-``autodiacsens``
-    auto-trigger diacritics sensitivity (raw index only). IF the index
-    is not stripped, decide if we automatically trigger diacritics
-    sensitivity if the search term has accented characters (not in
-    unac\_except\_trans). Else you need to use the query language and
-    the "D" modifier to specify diacritics sensitivity. Default is no.
-
-``autocasesens``
-    auto-trigger case sensitivity (raw index only). IF the index is not
-    stripped (see indexStripChars), decide if we automatically trigger
-    character case sensitivity if the search term has upper-case
-    characters in any but the first position. Else you need to use the
-    query language and the "C" modifier to specify character-case
-    sensitivity. Default is yes.
-
-``maxTermExpand``
-    Maximum query expansion count for a single term (e.g.: when using
-    wildcards). This only affects queries, not indexing. We used to not
-    limit this at all (except for filenames where the limit was too low
-    at 1000), but it is unreasonable with a big index. Default 10000.
-
-``maxXapianClauses``
-    Maximum number of clauses we add to a single Xapian query. This only
-    affects queries, not indexing. In some cases, the result of term
-    expansion can be multiplicative, and we want to avoid eating all the
-    memory. Default 50000.
-
-``snippetMaxPosWalk``
-    Maximum number of positions we walk while populating a snippet for
-    the result list. The default of 1,000,000 may be insufficient for
-    very big documents, the consequence would be snippets with possibly
-    meaning-altering missing words.
-
-Parameters for the PDF input script
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-``pdfocr``
-    Attempt OCR of PDF files with no text content if both tesseract and
-    pdftoppm are installed. The default is off because OCR is so very
-    slow.
-
-``pdfocrlang``
-    Language to assume for PDF OCR. This is very important for having a
-    reasonable rate of errors with tesseract. This can also be set
-    through a configuration variable or directory-local parameters. See
-    the rclpdf.py script.
-
-``pdfattach``
-    Enable PDF attachment extraction by executing pdftk (if available).
-    This is normally disabled, because it does slow down PDF indexing a
-    bit even if not one attachment is ever found.
-
-``pdfextrameta``
-    Extract text from selected XMP metadata tags. This is a
-    space-separated list of qualified XMP tag names. Each element can
-    also include a translation to a Recoll field name, separated by a
-    '\|' character. If the second element is absent, the tag name is
-    used as the Recoll field names. You will also need to add
-    specifications to the 'fields' file to direct processing of the
-    extracted data.
-
-``pdfextrametafix``
-    Define name of XMP field editing script. This defines the name of a
-    script to be loaded for editing XMP field values. The script should
-    define a 'MetaFixer' class with a metafix() method which will be
-    called with the qualified tag name and value of each selected field,
-    for editing or erasing. A new instance is created for each document,
-    so that the object can keep state for, e.g. eliminating duplicate
-    values.
-
-Parameters set for specific locations
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-``mhmboxquirks``
-    Enable thunderbird/mozilla-seamonkey mbox format quirks Set this for
-    the directory where the email mbox files are stored.
-
-The fields file
-~~~~~~~~~~~~~~~
-
-This file contains information about dynamic fields handling in RCL.
-Some very basic fields have hard-wired behaviour, and, mostly, you
-should not change the original data inside the ``fields`` file. But you
-can create custom fields fitting your data and handle them just like
-they were native ones.
-
-The ``fields`` file has several sections, which each define an aspect of
-fields processing. Quite often, you'll have to modify several sections
-to obtain the desired behaviour.
-
-We will only give a short description here, you should refer to the
-comments inside the default file for more detailed information.
-
-Field names should be lowercase alphabetic ASCII.
-
-[prefixes]
-    A field becomes indexed (searchable) by having a prefix defined in
-    this section. There is a more complete explanation of what prefixes
-    are in used by a standard recoll installation. In a nutshell:
-    extension prefixes should be all caps, begin with XY, and short.
-    E.g. XYMFLD.
-
-[values]
-    Fields listed in this section will be stored as XAP ``values``
-    inside the index. This makes them available for range queries,
-    allowing to filter results according to the field value. This
-    feature currently supports string and integer data. See the comments
-    in the file for more detail
-
-[stored]
-    A field becomes stored (displayable inside results) by having its
-    name listed in this section (typically with an empty value).
-
-[aliases]
-    This section defines lists of synonyms for the canonical names used
-    inside the ``[prefixes]`` and ``[stored]`` sections
-
-[queryaliases]
-    This section also defines aliases for the canonic field names, with
-    the difference that the substitution will only be used at query
-    time, avoiding any possibility that the value would pick-up random
-    metadata from documents.
-
-handler-specific sections
-    Some input handlers may need specific configuration for handling
-    fields. Only the email message handler currently has such a section
-    (named ``[mail]``). It allows indexing arbitrary email headers in
-    addition to the ones indexed by default. Other such sections may
-    appear in the future.
-
-Here follows a small example of a personal ``fields`` file. This would
-extract a specific email header and use it as a searchable field, with
-data displayable inside result lists. (Side note: as the email handler
-does no decoding on the values, only plain ascii headers can be indexed,
-and only the first occurrence will be used for headers that occur
-several times).
-
-::
-
-    [prefixes]
-            # Index mailmytag contents (with the given prefix)
-            mailmytag = XMTAG
-
-            [stored]
-            # Store mailmytag inside the document data record (so that it can be
-            # displayed - as %(mailmytag) - in result lists).
-            mailmytag = 
-
-            [queryaliases]
-            filename = fn
-            containerfilename = cfn
-
-            [mail]
-            # Extract the X-My-Tag mail header, and use it internally with the
-            # mailmytag field name
-            x-my-tag = mailmytag
-            
-
-Extended attributes in the fields file
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-RCL versions 1.19 and later process user extended file attributes as
-documents fields by default.
-
-Attributes are processed as fields of the same name, after removing the
-``user`` prefix on Linux.
-
-The ``[xattrtofields]`` section of the ``fields`` file allows specifying
-translations from extended attributes names to RCL field names. An empty
-translation disables use of the corresponding attribute data.
-
-The mimemap file
-~~~~~~~~~~~~~~~~
-
-``mimemap`` specifies the file name extension to MIME type mappings.
-
-For file names without an extension, or with an unknown one, a system
-command (``file`` ``-i``, or ``xdg-mime``) will be executed to determine
-the MIME type (this can be switched off, or the command changed inside
-the main configuration file).
-
-All extension values in ``mimemap`` must be entered in lower case. File
-names extensions are lower-cased for comparison during indexing, meaning
-that an upper case ``mimemap`` entry will never be matched.
-
-The mappings can be specified on a per-subtree basis, which may be
-useful in some cases. Example: okular notes have a ``.xml`` extension
-but should be handled specially, which is possible because they are
-usually all located in one place. Example:
-
-::
-
-    [~/.kde/share/apps/okular/docdata]
-            .xml = application/x-okular-notes
-
-The ``recoll_noindex`` ``mimemap`` variable has been moved to
-``recoll.conf`` and renamed to ``noContentSuffixes``, while keeping the
-same function, as of RCL version 1.21. For older RCL versions, see the
-documentation for ``noContentSuffixes`` but use ``recoll_noindex`` in
-``mimemap``.
-
-The mimeconf file
-~~~~~~~~~~~~~~~~~
-
-The main purpose of the ``mimeconf`` file is to specify how the
-different MIME types are handled for indexing. This is done in the
-``[index]`` section, which should not be modified casually. See the
-comments in the file.
-
-The file also contains other definitions which affect the query language
-and the GUI, and which, in retrospect, should have been stored
-elsewhere.
-
-The ``[icons]`` section allows you to change the icons which are
-displayed by the ``recoll`` GUI in the result lists (the values are the
-basenames of the ``png`` images inside the ``iconsdir`` directory (which
-is itself defined in ``recoll.conf``).
-
-The ``[categories]`` section defines the groupings of MIME types into
-``categories`` as used when adding an ``rclcat`` clause to a `query
-language <#RCL.SEARCH.LANG>`__ query. ``rclcat`` clauses are also used
-by the default ``guifilters`` buttons in the GUI (see next).
-
-The filter controls appear at the top of the ``recoll`` GUI, either as
-checkboxes just above the result list, or as a dropbox in the tool area.
-
-By default, they are labeled: ``media``, ``message``, ``other``,
-``presentation``, ``spreadsheet`` and ``text``, and each maps to a
-document category. This is determined in the ``[guifilters]`` section,
-where each control is defined by a variable naming a query language
-fragment.
-
-A simple exemple will hopefully make things clearer.
-
-::
-
-    [guifilters]
-
-    Big Books = dir:"~/My Books" size>10K
-    My Docs = dir:"~/My Documents"
-    Small Books = dir:"~/My Books" size<10K
-    System Docs = dir:/usr/share/doc
-            
-
-The above definition would create four filter checkboxes, labelled
-``Big Books``, ``My Docs``, etc.
-
-The text after the equal sign must be a valid query language fragment,
-and, when the button is checked, it will be combined with the rest of
-the query with an AND conjunction.
-
-Any name text before a colon character will be erased in the display,
-but used for sorting. You can use this to display the checkboxes in any
-order you like. For exemple, the following would do exactly the same as
-above, but ordering the checkboxes in the reverse order.
-
-::
-
-    [guifilters]
-
-    d:Big Books = dir:"~/My Books" size>10K
-    c:My Docs = dir:"~/My Documents"
-    b:Small Books = dir:"~/My Books" size<10K
-    a:System Docs = dir:/usr/share/doc
-            
-
-As you may have guessed, The default ``[guifilters]`` section looks
-like:
-
-::
-
-    [guifilters]
-    text = rclcat:text
-    spreadsheet = rclcat:spreadsheet
-    presentation = rclcat:presentation
-    media = rclcat:media
-    message = rclcat:message
-    other = rclcat:other
-            
-
-The mimeview file
-~~~~~~~~~~~~~~~~~
-
-``mimeview`` specifies which programs are started when you click on an
-Open link in a result list. Ie: HTML is normally displayed using
-firefox, but you may prefer Konqueror, your openoffice.org program might
-be named ``oofice`` instead of ``openoffice`` etc.
-
-Changes to this file can be done by direct editing, or through the
-``recoll`` GUI preferences dialog.
-
-If Use desktop preferences to choose document editor is checked in the
-RCL GUI preferences, all ``mimeview`` entries will be ignored except the
-one labelled ``application/x-all`` (which is set to use ``xdg-open`` by
-default).
-
-In this case, the ``xallexcepts`` top level variable defines a list of
-MIME type exceptions which will be processed according to the local
-entries instead of being passed to the desktop. This is so that specific
-RCL options such as a page number or a search string can be passed to
-applications that support them, such as the evince viewer.
-
-As for the other configuration files, the normal usage is to have a
-``mimeview`` inside your own configuration directory, with just the
-non-default entries, which will override those from the central
-configuration file.
-
-All viewer definition entries must be placed under a ``[view]`` section.
-
-The keys in the file are normally MIME types. You can add an application
-tag to specialize the choice for an area of the filesystem (using a
-``localfields`` specification in ``mimeconf``). The syntax for the key
-is mimetype\ ``|``\ tag
-
-The ``nouncompforviewmts`` entry, (placed at the top level, outside of
-the ``[view]`` section), holds a list of MIME types that should not be
-uncompressed before starting the viewer (if they are found compressed,
-ie: mydoc.doc.gz).
-
-The right side of each assignment holds a command to be executed for
-opening the file. The following substitutions are performed:
-
--  **%D.**
-
-   Document date
-
--  **%f.**
-
-   File name. This may be the name of a temporary file if it was
-   necessary to create one (ie: to extract a subdocument from a
-   container).
-
--  **%i.**
-
-   Internal path, for subdocuments of containers. The format depends on
-   the container type. If this appears in the command line, RCL will not
-   create a temporary file to extract the subdocument, expecting the
-   called application (possibly a script) to be able to handle it.
-
--  **%M.**
-
-   MIME type
-
--  **%p.**
-
-   Page index. Only significant for a subset of document types,
-   currently only PDF, Postscript and DVI files. Can be used to start
-   the editor at the right page for a match or snippet.
-
--  **%s.**
-
-   Search term. The value will only be set for documents with indexed
-   page numbers (ie: PDF). The value will be one of the matched search
-   terms. It would allow pre-setting the value in the "Find" entry
-   inside Evince for example, for easy highlighting of the term.
-
--  **%u.**
-
-   Url.
-
-In addition to the predefined values above, all strings like
-``%(fieldname)`` will be replaced by the value of the field named
-``fieldname`` for the document. This could be used in combination with
-field customisation to help with opening the document.
-
-The ``ptrans`` file
-~~~~~~~~~~~~~~~~~~~
-
-``ptrans`` specifies query-time path translations. These can be useful
-in `multiple cases <#RCL.SEARCH.PTRANS>`__.
-
-The file has a section for any index which needs translations, either
-the main one or additional query indexes. The sections are named with
-the XAP index directory names. No slash character should exist at the
-end of the paths (all comparisons are textual). An exemple should make
-things sufficiently clear
-
-::
-
-              [/home/me/.recoll/xapiandb]
-              /this/directory/moved = /to/this/place
-
-              [/path/to/additional/xapiandb]
-              /server/volume1/docdir = /net/server/volume1/docdir
-              /server/volume2/docdir = /net/server/volume2/docdir
-            
-
-Examples of configuration adjustments
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Adding an external viewer for an non-indexed type
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Imagine that you have some kind of file which does not have indexable
-content, but for which you would like to have a functional Open link in
-the result list (when found by file name). The file names end in .blob
-and can be displayed by application blobviewer.
-
-You need two entries in the configuration files for this to work:
-
--  In ``$RECOLL_CONFDIR/mimemap`` (typically ``~/.recoll/mimemap``), add
-   the following line:
-
-   ::
-
-                   .blob = application/x-blobapp
-                 
-
-   Note that the MIME type is made up here, and you could call it
-   diesel/oil just the same.
-
--  In ``$RECOLL_CONFDIR/mimeview`` under the ``[view]`` section, add:
-
-   ::
-
-                     application/x-blobapp = blobviewer %f
-                   
-
-   We are supposing that blobviewer wants a file name parameter here,
-   you would use ``%u`` if it liked URLs better.
-
-If you just wanted to change the application used by RCL to display a
-MIME type which it already knows, you would just need to edit
-``mimeview``. The entries you add in your personal file override those
-in the central configuration, which you do not need to alter.
-``mimeview`` can also be modified from the Gui.
-
-Adding indexing support for a new file type
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Let us now imagine that the above .blob files actually contain indexable
-text and that you know how to extract it with a command line program.
-Getting RCL to index the files is easy. You need to perform the above
-alteration, and also to add data to the ``mimeconf`` file (typically in
-``~/.recoll/mimeconf``):
-
--  Under the ``[index]`` section, add the following line (more about the
-   rclblob indexing script later):
-
-   ::
-
-       application/x-blobapp = exec rclblob
-
-   Or if the files are mostly text and you don't need to process them
-   for indexing:
-
-   ::
-
-       application/x-blobapp = internal text/plain
-
--  Under the ``[icons]`` section, you should choose an icon to be
-   displayed for the files inside the result lists. Icons are normally
-   64x64 pixels PNG files which live in ``/usr/share/recoll/images``.
-
--  Under the ``[categories]`` section, you should add the MIME type
-   where it makes sense (you can also create a category). Categories may
-   be used for filtering in advanced search.
-
-The rclblob handler should be an executable program or script which
-exists inside ``/usr/share/recoll/filters``. It will be given a file
-name as argument and should output the text or html contents on the
-standard output.
-
-The `filter programming <#RCL.PROGRAM.FILTERS>`__ section describes in
-more detail how to write an input handler.
diff --git a/src/doc/user/sphinx/_build/html/_sources/usermanual.txt b/src/doc/user/sphinx/_build/html/_sources/usermanual.txt
deleted file mode 100644
index da1fd782..00000000
--- a/src/doc/user/sphinx/_build/html/_sources/usermanual.txt
+++ /dev/null
@@ -1,5985 +0,0 @@
-==================
-Recoll user manual
-==================
-
-:Author: Jean-Francois Dockes
-
-.. contents::
-   :depth: 3
-..
-
-Introduction
-============
-
-This document introduces full text search notions and describes the
-installation and use of the RCL application. It is updated for RCL
-RCLVERSION.
-
-RCL was for a long time dedicated to Unix-like systems. It was only
-lately (2015) ported to MS-Windows. Many references in this manual,
-especially file locations, are specific to Unix, and not valid on WIN,
-where some described features are also not available. The manual will be
-progressively updated. Until this happens, on WIN, most references to
-shared files can be translated by looking under the Recoll installation
-directory (esp. the ``Share`` subdirectory). The user configuration is
-stored by default under ``AppData/Local/Recoll`` inside the user
-directory, along with the index itself.
-
-Giving it a try
----------------
-
-If you do not like reading manuals (who does?) but wish to give RCL a
-try, just `install <#RCL.INSTALL.BINARY>`__ the application and start
-the ``recoll`` graphical user interface (GUI), which will ask permission
-to index your home directory by default, allowing you to search
-immediately after indexing completes.
-
-Do not do this if your home directory contains a huge number of
-documents and you do not want to wait or are very short on disk space.
-In this case, you may first want to customize the
-`configuration <#RCL.INDEXING.CONFIG>`__ to restrict the indexed area
-(for the very impatient with a completed package install, from the
-``recoll`` GUI: Preferences > Indexing configuration, then adjust the
-Top directories section).
-
-On Unix/Linux, you may need to install the appropriate `supporting
-applications <#RCL.INSTALL.EXTERNAL>`__ for document types that need
-them (for example antiword for Microsoft Word files).
-
-The RCL for WIN package is self-contained and includes most useful
-auxiliary programs. You will just need to install Python 2.7.
-
-Full text search
-----------------
-
-RCL is a full text search application, which means that it finds your
-data by content rather than by external attributes (like the file name).
-You specify words (terms) which should or should not appear in the text
-you are looking for, and receive in return a list of matching documents,
-ordered so that the most *relevant* documents will appear first.
-
-You do not need to remember in what file or email message you stored a
-given piece of information. You just ask for related terms, and the tool
-will return a list of documents where these terms are prominent, in a
-similar way to Internet search engines.
-
-Full text search applications try to determine which documents are most
-relevant to the search terms you provide. Computer algorithms for
-determining relevance can be very complex, and in general are inferior
-to the power of the human mind to rapidly determine relevance. The
-quality of relevance guessing is probably the most important aspect when
-evaluating a search application. RCL relies on the XAP probabilistic
-information retrieval library to determine relevance.
-
-In many cases, you are looking for all the forms of a word, including
-plurals, different tenses for a verb, or terms derived from the same
-root or *stem* (example: floor, floors, floored, flooring...). Queries
-are usually automatically expanded to all such related terms (words that
-reduce to the same stem). This can be prevented for searching for a
-specific form.
-
-Stemming, by itself, does not accommodate for misspellings or phonetic
-searches. A full text search application may also support this form of
-approximation. For example, a search for aliterattion returning no
-result might propose alliteration, alteration, alterations, or
-altercation as possible replacement terms. RCL bases its suggestions on
-the actual index contents, so that suggestions may be made for words
-which would not appear in a standard dictionary.
-
-Recoll overview
----------------
-
-RCL uses the `XAP `__ information retrieval
-library as its storage and retrieval engine. XAP is a very mature
-package using `a sophisticated probabilistic ranking
-model `__.
-
-The XAP library manages an index database which describes where terms
-appear in your document files. It efficiently processes the complex
-queries which are produced by the RCL query expansion mechanism, and is
-in charge of the all-important relevance computation task.
-
-RCL provides the mechanisms and interface to get data into and out of
-the index. This includes translating the many possible document formats
-into pure text, handling term variations (using XAP stemmers), and
-spelling approximations (using the aspell speller), interpreting user
-queries and presenting results.
-
-In a shorter way, RCL does the dirty footwork, XAP deals with the
-intelligent parts of the process.
-
-The XAP index can be big (roughly the size of the original document
-set), but it is not a document archive. RCL can only display documents
-that still exist at the place from which they were indexed. (Actually,
-there is a way to reconstruct a document from the information in the
-index, but only the pure text is saved, possibly without punctuation and
-capitalization, depending on RCL version).
-
-RCL stores all internal data in Unicode UTF-8 format, and it can index
-files of many types with different character sets, encodings, and
-languages into the same index. It can process documents embedded inside
-other documents (for example a pdf document stored inside a Zip archive
-sent as an email attachment...), down to an arbitrary depth.
-
-Stemming is the process by which RCL reduces words to their radicals so
-that searching does not depend, for example, on a word being singular or
-plural (floor, floors), or on a verb tense (flooring, floored). Because
-the mechanisms used for stemming depend on the specific grammatical
-rules for each language, there is a separate XAP stemmer module for most
-common languages where stemming makes sense.
-
-RCL stores the unstemmed versions of terms in the main index and uses
-auxiliary databases for term expansion (one for each stemming language),
-which means that you can switch stemming languages between searches, or
-add a language without needing a full reindex.
-
-Storing documents written in different languages in the same index is
-possible, and commonly done. In this situation, you can specify several
-stemming languages for the index.
-
-RCL currently makes no attempt at automatic language recognition, which
-means that the stemmer will sometimes be applied to terms from other
-languages with potentially strange results. In practise, even if this
-introduces possibilities of confusion, this approach has been proven
-quite useful, and it is much less cumbersome than separating your
-documents according to what language they are written in.
-
-By default, RCL strips most accents and diacritics from terms, and
-converts them to lower case before either storing them in the index or
-searching for them. As a consequence, it is impossible to search for a
-particular capitalization of a term (``US`` / ``us``), or to
-discriminate two terms based on diacritics (``sake`` / ``saké``,
-``mate`` / ``maté``).
-
-RCL can optionally store the raw terms, without accent stripping or case
-conversion. In this configuration, default searches will behave as
-before, but it is possible to perform searches sensitive to case and
-diacritics. This is described in more detail in the `section about index
-case and diacritics sensitivity <#RCL.INDEXING.CONFIG.SENS>`__.
-
-RCL has many parameters which define exactly what to index, and how to
-classify and decode the source documents. These are kept in
-`configuration files <#RCL.INDEXING.CONFIG>`__. A default configuration
-is copied into a standard location (usually something like
-``/usr/share/recoll/examples``) during installation. The default values
-set by the configuration files in this directory may be overridden by
-values set inside your personal configuration, found by default in the
-``.recoll`` sub-directory of your home directory. The default
-configuration will index your home directory with default parameters and
-should be sufficient for giving RCL a try, but you may want to adjust it
-later, which can be done either by editing the text files or by using
-configuration menus in the ``recoll`` GUI. Some other parameters
-affecting only the ``recoll`` GUI are stored in the standard location
-defined by Qt.
-
-The `indexing process <#RCL.INDEXING.PERIODIC.EXEC>`__ is started
-automatically (after asking permission), the first time you execute the
-``recoll`` GUI. Indexing can also be performed by executing the
-``recollindex`` command. RCL indexing is multithreaded by default when
-appropriate hardware resources are available, and can perform in
-parallel multiple tasks for text extraction, segmentation and index
-updates.
-
-`Searches <#RCL.SEARCH>`__ are usually performed inside the ``recoll``
-GUI, which has many options to help you find what you are looking for.
-However, there are other ways to perform RCL searches:
-
--  A `command line interface <#RCL.SEARCH.COMMANDLINE>`__.
-
--  A `Python programming interface <#RCL.PROGRAM.PYTHONAPI>`__
-
--  A `KDE KIO slave module <#RCL.SEARCH.KIO>`__.
-
--  A Ubuntu Unity
-   `Scope `__
-   module.
-
--  A Gnome Shell `Search
-   Provider `__.
-
--  A `WEB interface `__.
-
-Indexing
-========
-
-Introduction
-------------
-
-Indexing is the process by which the set of documents is analyzed and
-the data entered into the database. RCL indexing is normally
-incremental: documents will only be processed if they have been modified
-since the last run. On the first execution, all documents will need
-processing. A full index build can be forced later by specifying an
-option to the indexing command (``recollindex`` ``-z`` or ``-Z``).
-
-``recollindex`` skips files which caused an error during a previous
-pass. This is a performance optimization, and a new behaviour in version
-1.21 (failed files were always retried by previous versions). The
-command line option ``-k`` can be set to retry failed files, for example
-after updating an input handler.
-
-The following sections give an overview of different aspects of the
-indexing processes and configuration, with links to detailed sections.
-
-Depending on your data, temporary files may be needed during indexing,
-some of them possibly quite big. You can use the RECOLL\_TMPDIR or
-TMPDIR environment variables to determine where they are created (the
-default is to use ``/tmp``). Using TMPDIR has the nice property that it
-may also be taken into account by auxiliary commands executed by
-``recollindex``.
-
-Indexing modes
-~~~~~~~~~~~~~~
-
-RCL indexing can be performed along two main modes:
-
--  **`Periodic (or batch) indexing: <#RCL.INDEXING.PERIODIC>`__.**
-
-   ``recollindex`` is executed at discrete times. The typical usage is
-   to have a nightly run `programmed <#RCL.INDEXING.PERIODIC.AUTOMAT>`__
-   into your ``cron`` file.
-
--  **`Real time indexing: <#RCL.INDEXING.MONITOR>`__.**
-
-   ``recollindex`` runs permanently as a daemon and uses a file system
-   alteration monitor (e.g. inotify) to detect file changes. New or
-   updated files are indexed at once.
-
-The choice between the two methods is mostly a matter of preference, and
-they can be combined by setting up multiple indexes (ie: use periodic
-indexing on a big documentation directory, and real time indexing on a
-small home directory). Monitoring a big file system tree can consume
-significant system resources.
-
-With RCL 1.24 and newer, it is also possible to set up an index so that
-only a subset of the tree will be monitored and the rest will be covered
-by batch/incremental indexing. (See the details in the `Real time
-indexing <#RCL.INDEXING.MONITOR>`__ section.
-
-The choice of method and the parameters used can be configured from the
-``recoll`` GUI: Preferences > Indexing schedule
-
-The GUI File menu also has entries to start or stop the current indexing
-operation. Stopping indexing is performed by killing the ``recollindex``
-process, which will checkpoint its state and exit. A later restart of
-indexing will mostly resume from where things stopped (the file tree
-walk has to be restarted from the beginning).
-
-When the real time indexer is running, two operations are available from
-the menu: 'Stop' and 'Trigger incremental pass'. When no indexing is
-running, you have a choice of updating the index or rebuilding it (the
-first choice only processes changed files, the second one zeroes the
-index before starting so that all files are processed).
-
-Configurations, multiple indexes
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-RCL supports defining multiple indexes, each defined by its own
-`configuration directory <#RCL.INDEXING.CONFIG>`__, in which several
-configuration files describe what should be indexed and how.
-
-A default personal configuration directory (``$HOME/.recoll/``) is
-created when a RCL program is first executed. This configuration is the
-one used for indexing and querying when no specific configuration is
-specified.
-
-All configuration parameters have defaults, defined in system-wide
-files. Without further customisation, the default configuration will
-process your complete home directory, with a reasonable set of defaults.
-It can be changed to process a different area of the file system, select
-files in different ways, and many other things.
-
-In some cases, it may be useful to create additional configuration
-directories, for example, to separate personal and shared indexes, or to
-take advantage of the organization of your data to improve search
-precision.
-
-A plausible usage scenario for the multiple index feature would be for a
-system administrator to set up a central index for shared data, that you
-choose to search or not in addition to your personal data. Of course,
-there are other possibilities. for example, there are many cases where
-you know the subset of files that should be searched, and where
-narrowing the search can improve the results. You can achieve
-approximately the same effect with the directory filter in advanced
-search, but multiple indexes may have better performance and may be
-worth the trouble in some cases.
-
-A more advanced use case would be to use multiple index to improve
-indexing performance, by updating several indexes in parallel (using
-multiple CPU cores and disks, or possibly several machines), and then
-merging them, or querying them in parallel.
-
-A specific configuration can be selected by setting the RECOLL\_CONFDIR
-environment variable, or giving the ``-c`` option to any of the RCL
-commands.
-
-When creating or updating indexes, the different configurations are
-entirely independant (no parameters are ever shared between
-configurations when indexing). The ``recollindex`` program always works
-on a single index.
-
-When querying, multiple indexes can be accessed concurrently, either
-from the GUI or the command line. When doing this, there is always one
-main configuration, from which both configuration and index data are
-used. Only the index data from the additional indexes is used (their
-configuration parameters are ignored).
-
-The behaviour of index update and query regarding multiple
-configurations is important and sometimes confusing, so it will be
-rephrased here: for index generation, multiple configurations are
-totally independant from each other. When querying, configuration and
-data are used from the main index (the one designated by ``-c`` or
-RECOLL\_CONFDIR), and only the data from the additional indexes is used.
-This implies that some parameters should be consistent among the
-configurations for indexes which are to be used together.
-
-See the section about `configuring multiple
-indexes <#RCL.INDEXING.CONFIG.MULTIPLE>`__ for more detail
-
-Document types
-~~~~~~~~~~~~~~
-
-RCL knows about quite a few different document types. The parameters for
-document types recognition and processing are set in `configuration
-files <#RCL.INDEXING.CONFIG>`__.
-
-Most file types, like HTML or word processing files, only hold one
-document. Some file types, like email folders or zip archives, can hold
-many individually indexed documents, which may themselves be compound
-ones. Such hierarchies can go quite deep, and RCL can process, for
-example, a LibreOffice document stored as an attachment to an email
-message inside an email folder archived in a zip file...
-
-``recollindex`` processes plain text, HTML, OpenDocument
-(Open/LibreOffice), email formats, and a few others internally.
-
-Other file types (ie: postscript, pdf, ms-word, rtf ...) need external
-applications for preprocessing. The list is in the
-`installation <#RCL.INSTALL.EXTERNAL>`__ section. After every indexing
-operation, RCL updates a list of commands that would be needed for
-indexing existing files types. This list can be displayed by selecting
-the menu option File > Show Missing Helpers in the ``recoll`` GUI. It is
-stored in the ``missing`` text file inside the configuration directory.
-
-By default, RCL will try to index any file type that it has a way to
-read. This is sometimes not desirable, and there are ways to either
-exclude some types, or on the contrary define a positive list of types
-to be indexed. In the latter case, any type not in the list will be
-ignored.
-
-Excluding files by name can be done by adding wildcard name patterns to
-the `skippedNames <#RCL.INSTALL.CONFIG.RECOLLCONF.SKIPPEDNAMES>`__ list,
-which can be done from the GUI Index configuration menu. Excluding by
-type can be done by setting the
-`excludedmimetypes <#RCL.INSTALL.CONFIG.RECOLLCONF.EXCLUDEDMIMETYPES>`__
-list in the configuration file (1.20 and later). This can be redefined
-for subdirectories.
-
-You can also define an exclusive list of MIME types to be indexed (no
-others will be indexed), by settting the
-`indexedmimetypes <#RCL.INSTALL.CONFIG.RECOLLCONF.INDEXEDMIMETYPES>`__
-configuration variable. Example:
-
-::
-
-            indexedmimetypes = text/html application/pdf
-          
-
-It is possible to redefine this parameter for subdirectories. Example:
-
-::
-
-          [/path/to/my/dir]
-          indexedmimetypes = application/pdf
-        
-
-(When using sections like this, don't forget that they remain in effect
-until the end of the file or another section indicator).
-
-``excludedmimetypes`` or ``indexedmimetypes``, can be set either by
-editing the `configuration file
-(``recoll.conf``) <#RCL.INSTALL.CONFIG.RECOLLCONF>`__ for the index, or
-by using the GUI index configuration tool.
-
-    **Note**
-
-    When editing the ``indexedmimetypes`` or ``excludedmimetypes``
-    lists, you should use the MIME values listed in the ``mimemap`` file
-    or in Recoll result lists in preference to ``file -i`` output: there
-    are a number of differences. The ``file -i`` output should only be
-    used for files without extensions, or for which the extension is not
-    listed in ``mimemap``
-
-Indexing failures
-~~~~~~~~~~~~~~~~~
-
-Indexing may fail for some documents, for a number of reasons: a helper
-program may be missing, the document may be corrupt, we may fail to
-uncompress a file because no file system space is available, etc.
-
-RCL versions prior to 1.21 always retried to index files which had
-previously caused an error. This guaranteed that anything that may have
-become indexable (for example because a helper had been installed) would
-be indexed. However this was bad for performance because some indexing
-failures may be quite costly (for example failing to uncompress a big
-file because of insufficient disk space).
-
-The indexer in RCL versions 1.21 and later does not retry failed files
-by default. Retrying will only occur if an explicit option (``-k``) is
-set on the ``recollindex`` command line, or if a script executed when
-``recollindex`` starts up says so. The script is defined by a
-configuration variable (``checkneedretryindexscript``), and makes a
-rather lame attempt at deciding if a helper command may have been
-installed, by checking if any of the common ``bin`` directories have
-changed.
-
-Recovery
-~~~~~~~~
-
-In the rare case where the index becomes corrupted (which can signal
-itself by weird search results or crashes), the index files need to be
-erased before restarting a clean indexing pass. Just delete the
-``xapiandb`` directory (see `next section <#RCL.INDEXING.STORAGE>`__),
-or, alternatively, start the next ``recollindex`` with the ``-z``
-option, which will reset the database before indexing. The difference
-between the two methods is that the second will not change the current
-index format, which may be undesirable if a newer format is supported by
-the XAP version.
-
-Index storage
--------------
-
-The default location for the index data is the ``xapiandb`` subdirectory
-of the RCL configuration directory, typically
-``$HOME/.recoll/xapiandb/``. This can be changed via two different
-methods (with different purposes):
-
-1. For a given configuration directory, you can specify a non-default
-   storage location for the index by setting the ``dbdir`` parameter in
-   the configuration file (see the `configuration
-   section <#RCL.INSTALL.CONFIG.RECOLLCONF>`__). This method would
-   mainly be of use if you wanted to keep the configuration directory in
-   its default location, but desired another location for the index,
-   typically out of disk occupation or performance concerns.
-
-2. You can specify a different configuration directory by setting the
-   RECOLL\_CONFDIR environment variable, or using the ``-c`` option to
-   the RCL commands. This method would typically be used to index
-   different areas of the file system to different indexes. For example,
-   if you were to issue the following command:
-
-   ::
-
-       recoll -c ~/.indexes-email
-
-   Then RCL would use configuration files stored in
-   ``~/.indexes-email/`` and, (unless specified otherwise in
-   ``recoll.conf``) would look for the index in
-   ``~/.indexes-email/xapiandb/``.
-
-   Using multiple configuration directories and `configuration
-   options <#RCL.INSTALL.CONFIG.RECOLLCONF>`__ allows you to tailor
-   multiple configurations and indexes to handle whatever subset of the
-   available data you wish to make searchable.
-
-The size of the index is determined by the size of the set of documents,
-but the ratio can vary a lot. For a typical mixed set of documents, the
-index size will often be close to the data set size. In specific cases
-(a set of compressed mbox files for example), the index can become much
-bigger than the documents. It may also be much smaller if the documents
-contain a lot of images or other non-indexed data (an extreme example
-being a set of mp3 files where only the tags would be indexed).
-
-Of course, images, sound and video do not increase the index size, which
-means that in most cases, the space used by the index will be negligible
-against the total amount of data on the computer.
-
-The index data directory (``xapiandb``) only contains data that can be
-completely rebuilt by an index run (as long as the original documents
-exist), and it can always be destroyed safely.
-
-XAP index formats
-~~~~~~~~~~~~~~~~~
-
-XAP versions usually support several formats for index storage. A given
-major XAP version will have a current format, used to create new
-indexes, and will also support the format from the previous major
-version.
-
-XAP will not convert automatically an existing index from the older
-format to the newer one. If you want to upgrade to the new format, or if
-a very old index needs to be converted because its format is not
-supported any more, you will have to explicitly delete the old index
-(typically ``~/.recoll/xapiandb``), then run a normal indexing command.
-Using ``recollindex`` option ``-z`` would not work in this situation.
-
-Security aspects
-~~~~~~~~~~~~~~~~
-
-The RCL index does not hold complete copies of the indexed documents (it
-almost does after version 1.24). But it does hold enough data to allow
-for an almost complete reconstruction. If confidential data is indexed,
-access to the database directory should be restricted.
-
-RCL will create the configuration directory with a mode of 0700 (access
-by owner only). As the index data directory is by default a
-sub-directory of the configuration directory, this should result in
-appropriate protection.
-
-If you use another setup, you should think of the kind of protection you
-need for your index, set the directory and files access modes
-appropriately, and also maybe adjust the ``umask`` used during index
-updates.
-
-Special considerations for big indexes
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This only needs concern you if your index is going to be bigger than
-around 5 GBytes. Beyond 10 GBytes, it becomes a serious issue. Most
-people have much smaller indexes. For reference, 5 GBytes would be
-around 2000 bibles, a lot of text. If you have a huge text dataset
-(remember: images don't count, the text content of PDFs is typically
-less than 5% of the file size), read on.
-
-The amount of writing performed by Xapian during index creation is not
-linear with the index size (it is somewhere between linear and
-quadratic). For big indexes this becomes a performance issue, and may
-even be an SSD disk wear issue.
-
-The problem can be mitigated by observing the following rules:
-
--  Partition the data set and create several indexes of reasonable size
-   rather than a huge one. These indexes can then be queried in parallel
-   (using the RCL external indexes facility), or merged using
-   ``xapian-compact``.
-
--  Have a lot of RAM available and set the ``idxflushmb`` RCL
-   configuration parameter as high as you can without swapping
-   (experimentation will be needed). 200 would be a minimum in this
-   context.
-
--  Use Xapian 1.4.10 or newer, as this version brought a significant
-   improvement in the amount of writes.
-
-Index configuration
--------------------
-
-Variables set inside the `RCL configuration
-files <#RCL.INSTALL.CONFIG>`__ control which areas of the file system
-are indexed, and how files are processed. These variables can be set
-either by editing the text files or by using the `dialogs in the
-``recoll`` GUI <#RCL.INDEXING.CONFIG.GUI>`__.
-
-The first time you start ``recoll``, you will be asked whether or not
-you would like it to build the index. If you want to adjust the
-configuration before indexing, just click Cancel at this point, which
-will get you into the configuration interface. If you exit at this
-point, ``recoll`` will have created a ``~/.recoll`` directory containing
-empty configuration files, which you can edit by hand.
-
-The configuration is documented inside the `installation
-chapter <#RCL.INSTALL.CONFIG>`__ of this document, or in the recoll.conf
-5 man page, but the most current information will most likely be the
-comments inside the sample file. The most immediately useful variable is
-probably ```topdirs`` <#RCL.INSTALL.CONFIG.RECOLLCONF.TOPDIRS>`__, which
-determines what subtrees and files get indexed.
-
-The applications needed to index file types other than text, HTML or
-email (ie: pdf, postscript, ms-word...) are described in the `external
-packages section. <#RCL.INSTALL.EXTERNAL>`__
-
-As of Recoll 1.18 there are two incompatible types of Recoll indexes,
-depending on the treatment of character case and diacritics. A `further
-section <#RCL.INDEXING.CONFIG.SENS>`__ describes the two types in more
-detail.
-
-Multiple indexes
-~~~~~~~~~~~~~~~~
-
-Multiple RCL indexes can be created by using several configuration
-directories which are typically set to index different areas of the file
-system. A specific index can be selected for updating or searching,
-using the RECOLL\_CONFDIR environment variable or the ``-c`` option to
-``recoll`` and ``recollindex``.
-
-Index configuration parameters can be set either by using a text editor
-on the files, or, for most parameters, by using the ``recoll`` index
-configuration GUI. In the latter case, the configuration directory for
-which parameters are modified is the one which was selected by
-RECOLL\_CONFDIR or the ``-c`` parameter, and there is no way to switch
-configurations within the GUI.
-
-As a remainder from a previous section, a ``recollindex`` program
-instance can only update one specific index, and it will only use
-parameters from a single configuration (no parameters are ever shared
-between configurations when indexing). All the query methods
-(``recoll``, ``recollq``, the Python API, etc.) operate with a main
-configuration, from which both configuration and index data are used,
-but can also query data from multiple additional indexes. Only the index
-data from the latter is used, their configuration parameters are
-ignored.
-
-When searching, the current main index (defined by RECOLL\_CONFDIR or
-``-c``) is always active. If this is undesirable, you can set up your
-base configuration to index an empty directory.
-
-If a set of multiple indexes are to be used together for searches, some
-configuration parameters must be consistent among the set. These are
-parameters which need to be the same when indexing and searching. As the
-parameters come from the main configuration when searching, they need to
-be compatible with what was set when creating the other indexes (which
-came from their respective configuration directories).
-
-Most importantly, all indexes to be queried concurrently must have the
-same option concerning character case and diacritics stripping, but
-there are other constraints. Most of the relevant parameters are
-described in the `linked
-section <#RCL.INSTALL.CONFIG.RECOLLCONF.TERMS>`__.
-
-The different search interfaces (GUI, command line, ...) have different
-methods to define the set of indexes to be used, see the appropriate
-section.
-
-At the moment, using multiple configurations implies a small level of
-command line usage. Additional configuration directories (beyond
-``~/.recoll``) must be created by hand (``mkdir`` or such), the GUI will
-not do it. This is to avoid mistakenly creating additional directories
-when an argument is mistyped. Also, the GUI or the indexer must be
-launched with a specific option or environment to work on the right
-configuration.
-
-To be more practical, here follows a few examples of the commands need
-to create, configure, update, and query an additional index.
-
-Initially creating the configuration and index:
-
-::
-
-    mkdir /path/to/my/new/config
-
-Configuring the new index can be done from the ``recoll`` GUI, launched
-from the command line to pass the ``-c`` option (you could create a
-desktop file to do it for you), and then using the GUI index
-configuration tool to set up the index.
-
-::
-
-    recoll -c /path/to/my/new/config
-
-Alternatively, you can just start a text editor on the main
-configuration file ```recoll.conf`` <#RCL.INSTALL.CONFIG.RECOLLCONF>`__.
-
-Creating and updating the index can be done from the command line:
-
-::
-
-    recollindex -c /path/to/my/new/config
-
-or from the File menu of a GUI launched with the same option
-(``recoll``, see above).
-
-The same GUI would also let you set up batch indexing for the new index.
-Real time indexing can only be set up from the GUI for the default index
-(the menu entry will be inactive if the GUI was started with a
-non-default ``-c`` option).
-
-The new index can be queried alone with
-
-::
-
-    recoll -c /path/to/my/new/config
-
-Or, in parallel with the default index, by starting ``recoll`` without a
-``-c`` option, and using the Preferences > External Index Dialog menu.
-
-Index case and diacritics sensitivity
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-As of RCL version 1.18 you have a choice of building an index with terms
-stripped of character case and diacritics, or one with raw terms. For a
-source term of ``Résumé``, the former will store ``resume``, the latter
-``Résumé``.
-
-Each type of index allows performing searches insensitive to case and
-diacritics: with a raw index, the user entry will be expanded to match
-all case and diacritics variations present in the index. With a stripped
-index, the search term will be stripped before searching.
-
-A raw index allows for another possibility which a stripped index cannot
-offer: using case and diacritics to discriminate between terms,
-returning different results when searching for ``US`` and ``us`` or
-``resume`` and ``résumé``. Read the `section about search case and
-diacritics sensitivity <#RCL.SEARCH.CASEDIAC>`__ for more details.
-
-The type of index to be created is controlled by the ``indexStripChars``
-configuration variable which can only be changed by editing the
-configuration file. Any change implies an index reset (not automated by
-RCL), and all indexes in a search must be set in the same way (again,
-not checked by RCL).
-
-If the ``indexStripChars`` is not set, RCL 1.18 creates a stripped index
-by default, for compatibility with previous versions.
-
-As a cost for added capability, a raw index will be slightly bigger than
-a stripped one (around 10%). Also, searches will be more complex, so
-probably slightly slower, and the feature is still young, so that a
-certain amount of weirdness cannot be excluded.
-
-One of the most adverse consequence of using a raw index is that some
-phrase and proximity searches may become impossible: because each term
-needs to be expanded, and all combinations searched for, the
-multiplicative expansion may become unmanageable.
-
-Indexing threads configuration
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The RCL indexing process ``recollindex`` can use multiple threads to
-speed up indexing on multiprocessor systems. The work done to index
-files is divided in several stages and some of the stages can be
-executed by multiple threads. The stages are:
-
-1. File system walking: this is always performed by the main thread.
-
-2. File conversion and data extraction.
-
-3. Text processing (splitting, stemming, etc.).
-
-4. XAP index update.
-
-You can also read a `longer
-document `__
-about the transformation of RCL indexing to multithreading.
-
-The threads configuration is controlled by two configuration file
-parameters.
-
-``thrQSizes``
-    This variable defines the job input queues configuration. There are
-    three possible queues for stages 2, 3 and 4, and this parameter
-    should give the queue depth for each stage (three integer values).
-    If a value of -1 is used for a given stage, no queue is used, and
-    the thread will go on performing the next stage. In practise, deep
-    queues have not been shown to increase performance. A value of 0 for
-    the first queue tells RCL to perform autoconfiguration (no need for
-    anything else in this case, thrTCounts is not used) - this is the
-    default configuration.
-
-``thrTCounts``
-    This defines the number of threads used for each stage. If a value
-    of -1 is used for one of the queue depths, the corresponding thread
-    count is ignored. It makes no sense to use a value other than 1 for
-    the last stage because updating the XAP index is necessarily
-    single-threaded (and protected by a mutex).
-
-    **Note**
-
-    If the first value in ``thrQSizes`` is 0, ``thrTCounts`` is ignored.
-
-The following example would use three queues (of depth 2), and 4 threads
-for converting source documents, 2 for processing their text, and one to
-update the index. This was tested to be the best configuration on the
-test system (quadri-processor with multiple disks).
-
-::
-
-              thrQSizes = 2 2 2
-              thrTCounts =  4 2 1
-            
-
-The following example would use a single queue, and the complete
-processing for each document would be performed by a single thread
-(several documents will still be processed in parallel in most cases).
-The threads will use mutual exclusion when entering the index update
-stage. In practise the performance would be close to the precedent case
-in general, but worse in certain cases (e.g. a Zip archive would be
-performed purely sequentially), so the previous approach is preferred.
-YMMV... The 2 last values for thrTCounts are ignored.
-
-::
-
-              thrQSizes = 2 -1 -1
-              thrTCounts =  6 1 1
-            
-
-The following example would disable multithreading. Indexing will be
-performed by a single thread.
-
-::
-
-              thrQSizes = -1 -1 -1
-            
-
-The index configuration GUI
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Most parameters for a given index configuration can be set from a
-``recoll`` GUI running on this configuration (either as default, or by
-setting RECOLL\_CONFDIR or the ``-c`` option.)
-
-The interface is started from the Preferences > Index Configuration menu
-entry. It is divided in four tabs, Global parameters, Local parameters,
-Web history (which is explained in the next section) and Search
-parameters.
-
-The Global parameters tab allows setting global variables, like the
-lists of top directories, skipped paths, or stemming languages.
-
-The Local parameters tab allows setting variables that can be redefined
-for subdirectories. This second tab has an initially empty list of
-customisation directories, to which you can add. The variables are then
-set for the currently selected directory (or at the top level if the
-empty line is selected).
-
-The Search parameters section defines parameters which are used at query
-time, but are global to an index and affect all search tools, not only
-the GUI.
-
-The meaning for most entries in the interface is self-evident and
-documented by a ``ToolTip`` popup on the text label. For more detail,
-you will need to refer to the `configuration
-section <#RCL.INSTALL.CONFIG>`__ of this guide.
-
-The configuration tool normally respects the comments and most of the
-formatting inside the configuration file, so that it is quite possible
-to use it on hand-edited files, which you might nevertheless want to
-backup first...
-
-Indexing the WEB pages which you wisit.
----------------------------------------
-
-With the help of a Firefox extension, RCL can index the Internet pages
-that you visit. The extension has a long history: it was initially
-designed for the Beagle indexer, then adapted to RCL and the Firefox XUL
-API. A new version of the addon has been written to work with the
-WebExtensions API, which is the only one supported after Firefox version
-57.
-
-The extension works by copying visited WEB pages to an indexing queue
-directory, which RCL then processes, indexing the data, storing it into
-a local cache, then removing the file from the queue.
-
-Because the WebExtensions API introduces more constraints to what
-extensions can do, the new version works with one more step: the files
-are first created in the browser default downloads location (typically
-``$HOME/Downloads`` ), then moved by a script in the old queue location.
-The script is automatically executed by the RCL indexer versions 1.23.5
-and newer. It could conceivably be executed independantly to make the
-new browser extension compatible with an older RCL version (the script
-is named ``recoll-we-move-files.py``).
-
-    **Note**
-
-    For the WebExtensions-based version to work, it is necessary to set
-    the ``webdownloadsdir`` value in the configuration if it was changed
-    from the default ``$HOME/Downloads`` in the browser preferences.
-
-The visited WEB pages indexing feature can be enabled on the RCL side
-from the GUI Index configuration panel, or by editing the configuration
-file (set ``processwebqueue`` to 1).
-
-A current pointer to the extension can be found, along with up-to-date
-instructions, on the `Recoll wiki <&FAQS;IndexWebHistory>`__.
-
-A copy of the indexed WEB pages is retained by Recoll in a local cache
-(from which previews can be fetched). The cache size can be adjusted
-from the Index configuration / Web history panel. Once the maximum size
-is reached, old pages are purged - both from the cache and the index -
-to make room for new ones, so you need to explicitly archive in some
-other place the pages that you want to keep indefinitely.
-
-Extended attributes data
-------------------------
-
-User extended attributes are named pieces of information that most
-modern file systems can attach to any file.
-
-RCL versions 1.19 and later process extended attributes as document
-fields by default. For older versions, this has to be activated at build
-time.
-
-A `freedesktop
-standard `__
-defines a few special attributes, which are handled as such by RCL:
-
-mime\_type
-    If set, this overrides any other determination of the file MIME
-    type.
-
-charset
-    If set, this defines the file character set (mostly useful for plain
-    text files).
-
-By default, other attributes are handled as RCL fields. On Linux, the
-``user`` prefix is removed from the name. This can be configured more
-precisely inside the ```fields`` configuration
-file <#RCL.INSTALL.CONFIG.FIELDS>`__.
-
-Importing external tags
------------------------
-
-During indexing, it is possible to import metadata for each file by
-executing commands. For example, this could extract user tag data for
-the file and store it in a field for indexing.
-
-See the `section about the ``metadatacmds``
-field <#RCL.INSTALL.CONFIG.RECOLLCONF.METADATACMDS>`__ in the main
-configuration chapter for a description of the configuration syntax.
-
-As an example, if you would want RCL to use tags managed by tmsu, you
-would add the following to the configuration file:
-
-::
-
-    [/some/area/of/the/fs]
-          metadatacmds = ; tags = tmsu tags %f
-          
-
-    **Note**
-
-    Depending on the tmsu version, you may need/want to add options like
-    ``--database=/some/db``.
-
-You may want to restrict this processing to a subset of the directory
-tree, because it may slow down indexing a bit
-(``[some/area/of/the/fs]``).
-
-Note the initial semi-colon after the equal sign.
-
-In the example above, the output of ``tmsu`` is used to set a field
-named ``tags``. The field name is arbitrary and could be ``tmsu`` or
-``myfield`` just the same, but ``tags`` is an alias for the standard RCL
-``keywords`` field, and the ``tmsu`` output will just augment its
-contents. This will avoid the need to extend the `field
-configuration <#RCL.PROGRAM.FIELDS>`__.
-
-Once re-indexing is performed (you'll need to force the file reindexing,
-RCL will not detect the need by itself), you will be able to search from
-the query language, through any of its aliases:
-``tags:some/alternate/values`` or ``tags:all,these,values`` (the compact
-field search syntax is supported for recoll 1.20 and later. For older
-versions, you would need to repeat the ``tags:`` specifier for each
-term, e.g. ``tags:some OR tags:alternate``).
-
-You should be aware that tags changes will not be detected by the
-indexer if the file itself did not change. One possible workaround would
-be to update the file ``ctime`` when you modify the tags, which would be
-consistent with how extended attributes function. A pair of ``chmod``
-commands could accomplish this, or a ``touch -a`` . Alternatively, just
-couple the tag update with a ``recollindex -e -i filename.``
-
-The PDF input handler
----------------------
-
-The PDF format is very important for scientific and technical
-documentation, and document archival. It has extensive facilities for
-storing metadata along with the document, and these facilities are
-actually used in the real world.
-
-In consequence, the ``rclpdf.py`` PDF input handler has more complex
-capabilities than most others, and it is also more configurable.
-Specifically, ``rclpdf.py`` can automatically use tesseract to perform
-OCR if the document text is empty, it can be configured to extract
-specific metadata tags from an XMP packet, and to extract PDF
-attachments.
-
-OCR with Tesseract
-~~~~~~~~~~~~~~~~~~
-
-If both tesseract and ``pdftoppm`` (generally from the poppler-utils
-package) are installed, the PDF handler may attempt OCR on PDF files
-with no text content. This is controlled by the
-`pdfocr <#RCL.INSTALL.CONFIG.RECOLLCONF.PDFOCR>`__ configuration
-variable, which is false by default because OCR is very slow.
-
-The choice of language is very important for successfull OCR. Recoll has
-currently no way to determine this from the document itself. You can set
-the language to use through the contents of a ``.ocrpdflang`` text file
-in the same directory as the PDF document, or through the
-RECOLL\_TESSERACT\_LANG environment variable, or through the contents of
-an ``ocrpdf`` text file inside the configuration directory. If none of
-the above are used, RCL will try to guess the language from the NLS
-environment.
-
-XMP fields extraction
-~~~~~~~~~~~~~~~~~~~~~
-
-The ``rclpdf.py`` script in RCL version 1.23.2 and later can extract XMP
-metadata fields by executing the ``pdfinfo`` command (usually found with
-poppler-utils). This is controlled by the
-`pdfextrameta <#RCL.INSTALL.CONFIG.RECOLLCONF.PDFEXTRAMETA>`__
-configuration variable, which specifies which tags to extract and,
-possibly, how to rename them.
-
-The `pdfextrametafix <#RCL.INSTALL.CONFIG.RECOLLCONF.PDFEXTRAMETAFIX>`__
-variable can be used to designate a file with Python code to edit the
-metadata fields (available for RCL 1.23.3 and later. 1.23.2 has
-equivalent code inside the handler script). Example:
-
-::
-
-    import sys
-            import re
-
-            class MetaFixer(object):
-            def __init__(self):
-            pass
-
-            def metafix(self, nm, txt):
-            if nm == 'bibtex:pages':
-            txt = re.sub(r'--', '-', txt)
-            elif nm == 'someothername':
-            # do something else
-            pass
-            elif nm == 'stillanother':
-            # etc.
-            pass
-            
-            return txt
-            def wrapup(self, metaheaders):
-            pass
-            
-
-If the 'metafix()' method is defined, it is called for each metadata
-field. A new MetaFixer object is created for each PDF document (so the
-object can keep state for, for example, eliminating duplicate values).
-If the 'wrapup()' method is defined, it is called at the end of XMP
-fields processing with the whole metadata as parameter, as an array of
-'(nm, val)' pairs, allowing an alternate approach for editing or
-adding/deleting fields.
-
-PDF attachment indexing
-~~~~~~~~~~~~~~~~~~~~~~~
-
-If pdftk is installed, and if the the
-`pdfattach <#RCL.INSTALL.CONFIG.RECOLLCONF.PDFATTACH>`__ configuration
-variable is set, the PDF input handler will try to extract PDF
-attachements for indexing as sub-documents of the PDF file. This is
-disabled by default, because it slows down PDF indexing a bit even if
-not one attachment is ever found (PDF attachments are uncommon in my
-experience).
-
-Periodic indexing
------------------
-
-Running indexing
-~~~~~~~~~~~~~~~~
-
-Indexing is always performed by the ``recollindex`` program, which can
-be started either from the command line or from the File menu in the
-``recoll`` GUI program. When started from the GUI, the indexing will run
-on the same configuration ``recoll`` was started on. When started from
-the command line, ``recollindex`` will use the RECOLL\_CONFDIR variable
-or accept a ``-c`` confdir option to specify a non-default configuration
-directory.
-
-If the ``recoll`` program finds no index when it starts, it will
-automatically start indexing (except if canceled).
-
-The ``recollindex`` indexing process can be interrupted by sending an
-interrupt (Ctrl-C, SIGINT) or terminate (SIGTERM) signal. Some time may
-elapse before the process exits, because it needs to properly flush and
-close the index. This can also be done from the ``recoll`` GUI File >
-Stop Indexing menu entry.
-
-After such an interruption, the index will be somewhat inconsistent
-because some operations which are normally performed at the end of the
-indexing pass will have been skipped (for example, the stemming and
-spelling databases will be inexistant or out of date). You just need to
-restart indexing at a later time to restore consistency. The indexing
-will restart at the interruption point (the full file tree will be
-traversed, but files that were indexed up to the interruption and for
-which the index is still up to date will not need to be reindexed).
-
-``recollindex`` has a number of other options which are described in its
-man page. Only a few will be described here.
-
-Option ``-z`` will reset the index when starting. This is almost the
-same as destroying the index files (the nuance is that the XAP format
-version will not be changed).
-
-Option ``-Z`` will force the update of all documents without resetting
-the index first. This will not have the "clean start" aspect of ``-z``,
-but the advantage is that the index will remain available for querying
-while it is rebuilt, which can be a significant advantage if it is very
-big (some installations need days for a full index rebuild).
-
-Option ``-k`` will force retrying files which previously failed to be
-indexed, for example because of a missing helper program.
-
-Of special interest also, maybe, are the ``-i`` and ``-f`` options.
-``-i`` allows indexing an explicit list of files (given as command line
-parameters or read on ``stdin``). ``-f`` tells ``recollindex`` to ignore
-file selection parameters from the configuration. Together, these
-options allow building a custom file selection process for some area of
-the file system, by adding the top directory to the ``skippedPaths``
-list and using an appropriate file selection method to build the file
-list to be fed to ``recollindex`` ``-if``. Trivial example:
-
-::
-
-              find . -name indexable.txt -print | recollindex -if
-            
-
-``recollindex`` ``-i`` will not descend into subdirectories specified as
-parameters, but just add them as index entries. It is up to the external
-file selection method to build the complete file list.
-
-Using ``cron`` to automate indexing
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The most common way to set up indexing is to have a cron task execute it
-every night. For example the following ``crontab`` entry would do it
-every day at 3:30AM (supposing ``recollindex`` is in your PATH):
-
-::
-
-            30 3 * * * recollindex > /some/tmp/dir/recolltrace 2>&1
-            
-
-Or, using ``anacron``:
-
-::
-
-            1  15  su mylogin -c "recollindex recollindex > /tmp/rcltraceme 2>&1"
-            
-
-As of version 1.17 the RCL GUI has dialogs to manage ``crontab`` entries
-for ``recollindex``. You can reach them from the Preferences > Indexing
-Schedule menu. They only work with the good old ``cron``, and do not
-give access to all features of ``cron`` scheduling.
-
-The usual command to edit your ``crontab`` is ``crontab`` ``-e`` (which
-will usually start the ``vi`` editor to edit the file). You may have
-more sophisticated tools available on your system.
-
-Please be aware that there may be differences between your usual
-interactive command line environment and the one seen by crontab
-commands. Especially the PATH variable may be of concern. Please check
-the crontab manual pages about possible issues.
-
-Real time indexing
-------------------
-
-Real time monitoring/indexing is performed by starting the
-``recollindex`` ``-m`` command. With this option, ``recollindex`` will
-detach from the terminal and become a daemon, permanently monitoring
-file changes and updating the index.
-
-While it is convenient that data is indexed in real time, repeated
-indexing can generate a significant load on the system when files such
-as email folders change. Also, monitoring large file trees by itself
-significantly taxes system resources. You probably do not want to enable
-it if your system is short on resources. Periodic indexing is adequate
-in most cases.
-
-As of RCL 1.24, you can set the
-`monitordirs <#RCL.INSTALL.CONFIG.RECOLLCONF.MONITORDIRS>`__
-configuration variable to specify that only a subset of your indexed
-files will be monitored for instant indexing. In this situation, an
-incremental pass on the full tree can be triggered by either restarting
-the indexer, or just running ``recollindex``, which will notify the
-running process. The ``recoll`` GUI also has a menu entry for this.
-
-Real time indexing: automatic daemon start
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Under KDE, Gnome and some other desktop environments, the daemon can
-automatically started when you log in, by creating a desktop file inside
-the ``~/.config/autostart`` directory. This can be done for you by the
-RCL GUI. Use the Preferences->Indexing Schedule menu.
-
-With older X11 setups, starting the daemon is normally performed as part
-of the user session script.
-
-The ``rclmon.sh`` script can be used to easily start and stop the
-daemon. It can be found in the ``examples`` directory (typically
-``/usr/local/[share/]recoll/examples``).
-
-For example, my out of fashion xdm-based session has a ``.xsession``
-script with the following lines at the end:
-
-::
-
-    recollconf=$HOME/.recoll-home
-            recolldata=/usr/local/share/recoll
-            RECOLL_CONFDIR=$recollconf $recolldata/examples/rclmon.sh start
-
-            fvwm 
-
-            
-
-The indexing daemon gets started, then the window manager, for which the
-session waits.
-
-By default the indexing daemon will monitor the state of the X11
-session, and exit when it finishes, it is not necessary to kill it
-explicitly. (The X11 server monitoring can be disabled with option
-``-x`` to ``recollindex``).
-
-If you use the daemon completely out of an X11 session, you need to add
-option ``-x`` to disable X11 session monitoring (else the daemon will
-not start).
-
-Real time indexing: miscellaneous details
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-By default, the messages from the indexing daemon will be sent to the
-same file as those from the interactive commands (``logfilename``). You
-may want to change this by setting the ``daemlogfilename`` and
-``daemloglevel`` configuration parameters. Also the log file will only
-be truncated when the daemon starts. If the daemon runs permanently, the
-log file may grow quite big, depending on the log level.
-
-When building RCL, the real time indexing support can be customised
-during package `configuration <#RCL.INSTALL.BUILDING>`__ with the
-``--with[out]-fam`` or ``--with[out]-inotify`` options. The default is
-currently to include inotify monitoring on systems that support it, and,
-as of RCL 1.17, gamin support on FreeBSD.
-
-    **Note**
-
-    On Linux systems, monitoring a big tree may need increasing the
-    resources available to inotify, which are normally defined in
-    ``/etc/sysctl.conf``.
-
-    ::
-
-                  ### inotify
-                  #
-                  # cat  /proc/sys/fs/inotify/max_queued_events   - 16384
-                  # cat  /proc/sys/fs/inotify/max_user_instances  - 128
-                  # cat  /proc/sys/fs/inotify/max_user_watches    - 16384
-                  #
-                  # -- Change to:
-                  #
-                  fs.inotify.max_queued_events=32768
-                  fs.inotify.max_user_instances=256
-                  fs.inotify.max_user_watches=32768
-                
-
-    Especially, you will need to trim your tree or adjust the
-    ``max_user_watches`` value if indexing exits with a message about
-    errno ``ENOSPC`` (28) from ``inotify_add_watch``.
-
-    **Note**
-
-    When using the real time monitor, it may happen that some files need
-    to be indexed, but change so often that they impose an excessive
-    load for the system.
-
-    RCL provides a configuration option to specify the minimum time
-    before which a file, specified by a wildcard pattern, cannot be
-    reindexed. See the ``mondelaypatterns`` parameter in the
-    `configuration section <#RCL.INSTALL.CONFIG.RECOLLCONF.MISC>`__.
-
-Searching
-=========
-
-Searching with the Qt graphical user interface
-----------------------------------------------
-
-The ``recoll`` program provides the main user interface for searching.
-It is based on the Qt library.
-
-``recoll`` has two search modes:
-
--  Simple search (the default, on the main screen) has a single entry
-   field where you can enter multiple words.
-
--  Advanced search (a panel accessed through the Tools menu or the
-   toolbox bar icon) has multiple entry fields, which you may use to
-   build a logical condition, with additional filtering on file type,
-   location in the file system, modification date, and size.
-
-In most cases, you can enter the terms as you think them, even if they
-contain embedded punctuation or other non-textual characters. For
-example, RCL can handle things like email addresses, or arbitrary cut
-and paste from another text window, punctation and all.
-
-The main case where you should enter text differently from how it is
-printed is for east-asian languages (Chinese, Japanese, Korean). Words
-composed of single or multiple characters should be entered separated by
-white space in this case (they would typically be printed without white
-space).
-
-Some searches can be quite complex, and you may want to re-use them
-later, perhaps with some tweaking. RCL versions 1.21 and later can save
-and restore searches, using XML files. See `Saving and restoring
-queries <#RCL.SEARCH.SAVING>`__.
-
-Simple search
-~~~~~~~~~~~~~
-
-Start the ``recoll`` program.
-
-Possibly choose a search mode: Any term, All terms, File name or Query
-language.
-
-Enter search term(s) in the text field at the top of the window.
-
-Click the Search button or hit the Enter key to start the search.
-
-The initial default search mode is Query language. Without special
-directives, this will look for documents containing all of the search
-terms (the ones with more terms will get better scores), just like the
-All terms mode. Any term will search for documents where at least one of
-the terms appear.
-
-The Query Language features are described in `a separate
-section <#RCL.SEARCH.LANG>`__.
-
-All search modes allow terms to be expanded with wildcards characters
-(``*``, ``?``, ``[]``). See the `section about
-wildcards <#RCL.SEARCH.WILDCARDS>`__ for more details.
-
-The File name search mode will specifically look for file names. The
-point of having a separate file name search is that wild card expansion
-can be performed more efficiently on a small subset of the index
-(allowing wild cards on the left of terms without excessive penality).
-Things to know:
-
--  White space in the entry should match white space in the file name,
-   and is not treated specially.
-
--  The search is insensitive to character case and accents,
-   independantly of the type of index.
-
--  An entry without any wild card character and not capitalized will be
-   prepended and appended with '\*' (ie: etc -> \*etc\*, but Etc ->
-   etc).
-
--  If you have a big index (many files), excessively generic fragments
-   may result in inefficient searches.
-
-In all modes except File name, you can search for exact phrases
-(adjacent words in a given order) by enclosing the input inside double
-quotes. Ex: ``"virtual reality"``.
-
-When using a stripped index (the default), character case has no
-influence on search, except that you can disable stem expansion for any
-term by capitalizing it. Ie: a search for ``floor`` will also normally
-look for ``flooring``, ``floored``, etc., but a search for ``Floor``
-will only look for ``floor``, in any character case. Stemming can also
-be disabled globally in the preferences. When using a raw index, `the
-rules are a bit more complicated <#RCL.SEARCH.CASEDIAC>`__.
-
-RCL remembers the last few searches that you performed. You can directly
-access the search history by clicking the clock button on the right of
-the search entry, while the latter is empty. Otherwise, the history is
-used for entry completion (see next). Only the search texts are
-remembered, not the mode (all/any/file name).
-
-While text is entered in the search area, ``recoll`` will display
-possible completions, filtered from the history and the index search
-terms. This can be disabled with a GUI Preferences option.
-
-Double-clicking on a word in the result list or a preview window will
-insert it into the simple search entry field.
-
-You can cut and paste any text into an All terms or Any term search
-field, punctuation, newlines and all - except for wildcard characters
-(single ``?`` characters are ok). RCL will process it and produce a
-meaningful search. This is what most differentiates this mode from the
-Query Language mode, where you have to care about the syntax.
-
-You can use the `Tools > Advanced search <#RCL.SEARCH.GUI.COMPLEX>`__
-dialog for more complex searches.
-
-The default result list
-~~~~~~~~~~~~~~~~~~~~~~~
-
-After starting a search, a list of results will instantly be displayed
-in the main list window.
-
-By default, the document list is presented in order of relevance (how
-well the system estimates that the document matches the query). You can
-sort the result by ascending or descending date by using the vertical
-arrows in the toolbar.
-
-Clicking on the ``Preview`` link for an entry will open an internal
-preview window for the document. Further ``Preview`` clicks for the same
-search will open tabs in the existing preview window. You can use
-Shift+Click to force the creation of another preview window, which may
-be useful to view the documents side by side. (You can also browse
-successive results in a single preview window by typing
-Shift+ArrowUp/Down in the window).
-
-Clicking the ``Open`` link will start an external viewer for the
-document. By default, RCL lets the desktop choose the appropriate
-application for most document types (there is a short list of
-exceptions, see further). If you prefer to completely customize the
-choice of applications, you can uncheck the Use desktop preferences
-option in the GUI preferences dialog, and click the Choose editor
-applications button to adjust the predefined RCL choices. The tool
-accepts multiple selections of MIME types (e.g. to set up the editor for
-the dozens of office file types).
-
-Even when Use desktop preferences is checked, there is a small list of
-exceptions, for MIME types where the RCL choice should override the
-desktop one. These are applications which are well integrated with RCL,
-especially evince for viewing PDF and Postscript files because of its
-support for opening the document at a specific page and passing a search
-string as an argument. Of course, you can edit the list (in the GUI
-preferences) if you would prefer to lose the functionality and use the
-standard desktop tool.
-
-You may also change the choice of applications by editing the
-```mimeview`` <#RCL.INSTALL.CONFIG.MIMEVIEW>`__ configuration file if
-you find this more convenient.
-
-Each result entry also has a right-click menu with an Open With entry.
-This lets you choose an application from the list of those which
-registered with the desktop for the document MIME type.
-
-The ``Preview`` and ``Open`` edit links may not be present for all
-entries, meaning that RCL has no configured way to preview a given file
-type (which was indexed by name only), or no configured external editor
-for the file type. This can sometimes be adjusted simply by tweaking the
-```mimemap`` <#RCL.INSTALL.CONFIG.MIMEMAP>`__ and
-```mimeview`` <#RCL.INSTALL.CONFIG.MIMEVIEW>`__ configuration files (the
-latter can be modified with the user preferences dialog).
-
-The format of the result list entries is entirely configurable by using
-the preference dialog to `edit an HTML
-fragment <#RCL.SEARCH.GUI.CUSTOM.RESLIST>`__.
-
-You can click on the ``Query details`` link at the top of the results
-page to see the query actually performed, after stem expansion and other
-processing.
-
-Double-clicking on any word inside the result list or a preview window
-will insert it into the simple search text.
-
-The result list is divided into pages (the size of which you can change
-in the preferences). Use the arrow buttons in the toolbar or the links
-at the bottom of the page to browse the results.
-
-No results: the spelling suggestions
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-When a search yields no result, and if the aspell dictionary is
-configured, RCL will try to check for misspellings among the query
-terms, and will propose lists of replacements. Clicking on one of the
-suggestions will replace the word and restart the search. You can hold
-any of the modifier keys (Ctrl, Shift, etc.) while clicking if you would
-rather stay on the suggestion screen because several terms need
-replacement.
-
-The result list right-click menu
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Apart from the preview and edit links, you can display a pop-up menu by
-right-clicking over a paragraph in the result list. This menu has the
-following entries:
-
--  Preview
-
--  Open
-
--  Open With
-
--  Run Script
-
--  Copy File Name
-
--  Copy Url
-
--  Save to File
-
--  Find similar
-
--  Preview Parent document
-
--  Open Parent document
-
--  Open Snippets Window
-
-The Preview and Open entries do the same thing as the corresponding
-links.
-
-Open With lets you open the document with one of the applications
-claiming to be able to handle its MIME type (the information comes from
-the ``.desktop`` files in ``/usr/share/applications``).
-
-Run Script allows starting an arbitrary command on the result file. It
-will only appear for results which are top-level files. See
-`further <#RCL.SEARCH.GUI.RUNSCRIPT>`__ for a more detailed description.
-
-The Copy File Name and Copy Url copy the relevant data to the clipboard,
-for later pasting.
-
-Save to File allows saving the contents of a result document to a chosen
-file. This entry will only appear if the document does not correspond to
-an existing file, but is a subdocument inside such a file (ie: an email
-attachment). It is especially useful to extract attachments with no
-associated editor.
-
-The Open/Preview Parent document entries allow working with the higher
-level document (e.g. the email message an attachment comes from). RCL is
-sometimes not totally accurate as to what it can or can't do in this
-area. For example the Parent entry will also appear for an email which
-is part of an mbox folder file, but you can't actually visualize the
-mbox (there will be an error dialog if you try).
-
-If the document is a top-level file, Open Parent will start the default
-file manager on the enclosing filesystem directory.
-
-The Find similar entry will select a number of relevant term from the
-current document and enter them into the simple search field. You can
-then start a simple search, with a good chance of finding documents
-related to the current result. I can't remember a single instance where
-this function was actually useful to me...
-
-The Open Snippets Window entry will only appear for documents which
-support page breaks (typically PDF, Postscript, DVI). The snippets
-window lists extracts from the document, taken around search terms
-occurrences, along with the corresponding page number, as links which
-can be used to start the native viewer on the appropriate page. If the
-viewer supports it, its search function will also be primed with one of
-the search terms.
-
-The result table
-~~~~~~~~~~~~~~~~
-
-In RCL 1.15 and newer, the results can be displayed in spreadsheet-like
-fashion. You can switch to this presentation by clicking the table-like
-icon in the toolbar (this is a toggle, click again to restore the list).
-
-Clicking on the column headers will allow sorting by the values in the
-column. You can click again to invert the order, and use the header
-right-click menu to reset sorting to the default relevance order (you
-can also use the sort-by-date arrows to do this).
-
-Both the list and the table display the same underlying results. The
-sort order set from the table is still active if you switch back to the
-list mode. You can click twice on a date sort arrow to reset it from
-there.
-
-The header right-click menu allows adding or deleting columns. The
-columns can be resized, and their order can be changed (by dragging).
-All the changes are recorded when you quit ``recoll``
-
-Hovering over a table row will update the detail area at the bottom of
-the window with the corresponding values. You can click the row to
-freeze the display. The bottom area is equivalent to a result list
-paragraph, with links for starting a preview or a native application,
-and an equivalent right-click menu. Typing Esc (the Escape key) will
-unfreeze the display.
-
-Running arbitrary commands on result files (1.20 and later)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Apart from the Open and Open With operations, which allow starting an
-application on a result document (or a temporary copy), based on its
-MIME type, it is also possible to run arbitrary commands on results
-which are top-level files, using the Run Script entry in the results
-pop-up menu.
-
-The commands which will appear in the Run Script submenu must be defined
-by ``.desktop`` files inside the ``scripts`` subdirectory of the current
-configuration directory.
-
-Here follows an example of a ``.desktop`` file, which could be named for
-example, ``~/.recoll/scripts/myscript.desktop`` (the exact file name
-inside the directory is irrelevant):
-
-::
-
-              [Desktop Entry]
-              Type=Application
-              Name=MyFirstScript
-              Exec=/home/me/bin/tryscript %F
-              MimeType=*/*
-            
-
-The ``Name`` attribute defines the label which will appear inside the
-Run Script menu. The ``Exec`` attribute defines the program to be run,
-which does not need to actually be a script, of course. The ``MimeType``
-attribute is not used, but needs to exist.
-
-The commands defined this way can also be used from links inside the
-`result paragraph <#RCL.SEARCH.GUI.CUSTOM.RESLIST.PARA>`__.
-
-As an example, it might make sense to write a script which would move
-the document to the trash and purge it from the RCL index.
-
-Displaying thumbnails
-~~~~~~~~~~~~~~~~~~~~~
-
-The default format for the result list entries and the detail area of
-the result table display an icon for each result document. The icon is
-either a generic one determined from the MIME type, or a thumbnail of
-the document appearance. Thumbnails are only displayed if found in the
-standard freedesktop location, where they would typically have been
-created by a file manager.
-
-Recoll has no capability to create thumbnails. A relatively simple trick
-is to use the Open parent document/folder entry in the result list popup
-menu. This should open a file manager window on the containing
-directory, which should in turn create the thumbnails (depending on your
-settings). Restarting the search should then display the thumbnails.
-
-There are also `some pointers about thumbnail
-generation <&FAQS;ResultsThumbnails.wiki>`__ on the RCL wiki.
-
-The preview window
-~~~~~~~~~~~~~~~~~~
-
-The preview window opens when you first click a ``Preview`` link inside
-the result list.
-
-Subsequent preview requests for a given search open new tabs in the
-existing window (except if you hold the Shift key while clicking which
-will open a new window for side by side viewing).
-
-Starting another search and requesting a preview will create a new
-preview window. The old one stays open until you close it.
-
-You can close a preview tab by typing Ctrl-W (Ctrl + W) in the window.
-Closing the last tab for a window will also close the window.
-
-Of course you can also close a preview window by using the window
-manager button in the top of the frame.
-
-You can display successive or previous documents from the result list
-inside a preview tab by typing Shift+Down or Shift+Up (Down and Up are
-the arrow keys).
-
-A right-click menu in the text area allows switching between displaying
-the main text or the contents of fields associated to the document (ie:
-author, abtract, etc.). This is especially useful in cases where the
-term match did not occur in the main text but in one of the fields. In
-the case of images, you can switch between three displays: the image
-itself, the image metadata as extracted by ``exiftool`` and the fields,
-which is the metadata stored in the index.
-
-You can print the current preview window contents by typing Ctrl-P (Ctrl
-+ P) in the window text.
-
-Searching inside the preview
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The preview window has an internal search capability, mostly controlled
-by the panel at the bottom of the window, which works in two modes: as a
-classical editor incremental search, where we look for the text entered
-in the entry zone, or as a way to walk the matches between the document
-and the RCL query that found it.
-
-Incremental text search
-    The preview tabs have an internal incremental search function. You
-    initiate the search either by typing a / (slash) or CTL-F inside the
-    text area or by clicking into the Search for: text field and
-    entering the search string. You can then use the Next and Previous
-    buttons to find the next/previous occurrence. You can also type F3
-    inside the text area to get to the next occurrence.
-
-    If you have a search string entered and you use Ctrl-Up/Ctrl-Down to
-    browse the results, the search is initiated for each successive
-    document. If the string is found, the cursor will be positioned at
-    the first occurrence of the search string.
-
-Walking the match lists
-    If the entry area is empty when you click the Next or Previous
-    buttons, the editor will be scrolled to show the next match to any
-    search term (the next highlighted zone). If you select a search
-    group from the dropdown list and click Next or Previous, the match
-    list for this group will be walked. This is not the same as a text
-    search, because the occurences will include non-exact matches (as
-    caused by stemming or wildcards). The search will revert to the text
-    mode as soon as you edit the entry area.
-
-The Query Fragments window
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Selecting the Tools > Query Fragments menu entry will open a window with
-radio- and check-buttons which can be used to activate query language
-fragments for filtering the current query. This can be useful if you
-have frequent reusable selectors, for example, filtering on alternate
-directories, or searching just one category of files, not covered by the
-standard category selectors.
-
-The contents of the window are entirely customizable, and defined by the
-contents of the ``fragbuts.xml`` file inside the configuration
-directory. The sample file distributed with RCL (which you should be
-able to find under ``/usr/share/recoll/examples/fragbuts.xml``),
-contains an example which filters the results from the WEB history.
-
-Here follows an example:
-
-::
-
-              
-
-              
-
-              
-
-              
-              
-              
-              
-
-              
-              
-              -rclbes:BGL
-              
-
-              
-              
-              rclbes:BGL
-              
-
-              
-
-              
-
-              
-              
-              date:2010-01-01/2010-12-31
-              
-
-              
-              
-              dir:/my/great/directory
-              
-
-              
-              
-            
-
-Each ``radiobuttons`` or ``buttons`` section defines a line of
-checkbuttons or radiobuttons inside the window. Any number of buttons
-can be selected, but the radiobuttons in a line are exclusive.
-
-Each ``fragbut`` section defines the label for a button, and the Query
-Language fragment which will be added (as an AND filter) before
-performing the query if the button is active.
-
-This feature is new in RCL 1.20, and will probably be refined depending
-on user feedback.
-
-Complex/advanced search
-~~~~~~~~~~~~~~~~~~~~~~~
-
-The advanced search dialog helps you build more complex queries without
-memorizing the search language constructs. It can be opened through the
-Tools menu or through the main toolbar.
-
-RCL keeps a history of searches. See `Advanced search
-history <#RCL.SEARCH.GUI.COMPLEX.HISTORY>`__.
-
-The dialog has two tabs:
-
-1. The first tab lets you specify terms to search for, and permits
-   specifying multiple clauses which are combined to build the search.
-
-2. The second tab lets filter the results according to file size, date
-   of modification, MIME type, or location.
-
-Click on the Start Search button in the advanced search dialog, or type
-Enter in any text field to start the search. The button in the main
-window always performs a simple search.
-
-Click on the ``Show query details`` link at the top of the result page
-to see the query expansion.
-
-Avanced search: the "find" tab
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-This part of the dialog lets you constructc a query by combining
-multiple clauses of different types. Each entry field is configurable
-for the following modes:
-
--  All terms.
-
--  Any term.
-
--  None of the terms.
-
--  Phrase (exact terms in order within an adjustable window).
-
--  Proximity (terms in any order within an adjustable window).
-
--  Filename search.
-
-Additional entry fields can be created by clicking the Add clause
-button.
-
-When searching, the non-empty clauses will be combined either with an
-AND or an OR conjunction, depending on the choice made on the left (All
-clauses or Any clause).
-
-Entries of all types except "Phrase" and "Near" accept a mix of single
-words and phrases enclosed in double quotes. Stemming and wildcard
-expansion will be performed as for simple search.
-
-**Phrases and Proximity searches.**
-
-These two clauses work in similar ways, with the difference that
-proximity searches do not impose an order on the words. In both cases,
-an adjustable number (slack) of non-matched words may be accepted
-between the searched ones (use the counter on the left to adjust this
-count). For phrases, the default count is zero (exact match). For
-proximity it is ten (meaning that two search terms, would be matched if
-found within a window of twelve words). Examples: a phrase search for
-``quick fox`` with a slack of 0 will match ``quick fox`` but not
-``quick brown fox``. With a slack of 1 it will match the latter, but not
-``fox quick``. A proximity search for ``quick fox`` with the default
-slack will match the latter, and also
-``a fox is a cunning and quick animal``.
-
-Avanced search: the "filter" tab
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-This part of the dialog has several sections which allow filtering the
-results of a search according to a number of criteria
-
--  The first section allows filtering by dates of last modification. You
-   can specify both a minimum and a maximum date. The initial values are
-   set according to the oldest and newest documents found in the index.
-
--  The next section allows filtering the results by file size. There are
-   two entries for minimum and maximum size. Enter decimal numbers. You
-   can use suffix multipliers: ``k/K``, ``m/M``, ``g/G``, ``t/T`` for
-   1E3, 1E6, 1E9, 1E12 respectively.
-
--  The next section allows filtering the results by their MIME types, or
-   MIME categories (ie: media/text/message/etc.).
-
-   You can transfer the types between two boxes, to define which will be
-   included or excluded by the search.
-
-   The state of the file type selection can be saved as the default (the
-   file type filter will not be activated at program start-up, but the
-   lists will be in the restored state).
-
--  The bottom section allows restricting the search results to a
-   sub-tree of the indexed area. You can use the Invert checkbox to
-   search for files not in the sub-tree instead. If you use directory
-   filtering often and on big subsets of the file system, you may think
-   of setting up multiple indexes instead, as the performance may be
-   better.
-
-   You can use relative/partial paths for filtering. Ie, entering
-   ``dirA/dirB`` would match either ``/dir1/dirA/dirB/myfile1`` or
-   ``/dir2/dirA/dirB/someother/myfile2``.
-
-Avanced search history
-^^^^^^^^^^^^^^^^^^^^^^
-
-The advanced search tool memorizes the last 100 searches performed. You
-can walk the saved searches by using the up and down arrow keys while
-the keyboard focus belongs to the advanced search dialog.
-
-The complex search history can be erased, along with the one for simple
-search, by selecting the File > Erase Search History menu entry.
-
-The term explorer tool
-~~~~~~~~~~~~~~~~~~~~~~
-
-RCL automatically manages the expansion of search terms to their
-derivatives (ie: plural/singular, verb inflections). But there are other
-cases where the exact search term is not known. For example, you may not
-remember the exact spelling, or only know the beginning of the name.
-
-The search will only propose replacement terms with spelling variations
-when no matching document were found. In some cases, both proper
-spellings and mispellings are present in the index, and it may be
-interesting to look for them explicitely.
-
-The term explorer tool (started from the toolbar icon or from the Term
-explorer entry of the Tools menu) can be used to search the full index
-terms list. It has three modes of operations:
-
-Wildcard
-    In this mode of operation, you can enter a search string with
-    shell-like wildcards (\*, ?, []). ie: xapi\* would display all index
-    terms beginning with xapi. (More about wildcards
-    `here <#RCL.SEARCH.WILDCARDS>`__ ).
-
-Regular expression
-    This mode will accept a regular expression as input. Example:
-    word[0-9]+. The expression is implicitely anchored at the beginning.
-    Ie: press will match pression but not expression. You can use
-    .\*press to match the latter, but be aware that this will cause a
-    full index term list scan, which can be quite long.
-
-Stem expansion
-    This mode will perform the usual stem expansion normally done as
-    part user input processing. As such it is probably mostly useful to
-    demonstrate the process.
-
-Spelling/Phonetic
-    In this mode, you enter the term as you think it is spelled, and RCL
-    will do its best to find index terms that sound like your entry.
-    This mode uses the Aspell spelling application, which must be
-    installed on your system for things to work (if your documents
-    contain non-ascii characters, RCL needs an aspell version newer than
-    0.60 for UTF-8 support). The language which is used to build the
-    dictionary out of the index terms (which is done at the end of an
-    indexing pass) is the one defined by your NLS environment. Weird
-    things will probably happen if languages are mixed up.
-
-Note that in cases where RCL does not know the beginning of the string
-to search for (ie a wildcard expression like \*coll), the expansion can
-take quite a long time because the full index term list will have to be
-processed. The expansion is currently limited at 10000 results for
-wildcards and regular expressions. It is possible to change the limit in
-the configuration file.
-
-Double-clicking on a term in the result list will insert it into the
-simple search entry field. You can also cut/paste between the result
-list and any entry field (the end of lines will be taken care of).
-
-Multiple indexes
-~~~~~~~~~~~~~~~~
-
-See the `section describing the use of multiple
-indexes <#RCL.INDEXING.CONFIG.MULTIPLE>`__ for generalities. Only the
-aspects concerning the ``recoll`` GUI are described here.
-
-A ``recoll`` program instance is always associated with a specific
-index, which is the one to be updated when requested from the File menu,
-but it can use any number of RCL indexes for searching. The external
-indexes can be selected through the external indexes tab in the
-preferences dialog.
-
-Index selection is performed in two phases. A set of all usable indexes
-must first be defined, and then the subset of indexes to be used for
-searching. These parameters are retained across program executions
-(there are kept separately for each RCL configuration). The set of all
-indexes is usually quite stable, while the active ones might typically
-be adjusted quite frequently.
-
-The main index (defined by RECOLL\_CONFDIR) is always active. If this is
-undesirable, you can set up your base configuration to index an empty
-directory.
-
-When adding a new index to the set, you can select either a RCL
-configuration directory, or directly a XAP index directory. In the first
-case, the XAP index directory will be obtained from the selected
-configuration.
-
-As building the set of all indexes can be a little tedious when done
-through the user interface, you can use the RECOLL\_EXTRA\_DBS
-environment variable to provide an initial set. This might typically be
-set up by a system administrator so that every user does not have to do
-it. The variable should define a colon-separated list of index
-directories, ie:
-
-::
-
-    export RECOLL_EXTRA_DBS=/some/place/xapiandb:/some/other/db
-
-Another environment variable, RECOLL\_ACTIVE\_EXTRA\_DBS allows adding
-to the active list of indexes. This variable was suggested and
-implemented by a RCL user. It is mostly useful if you use scripts to
-mount external volumes with RCL indexes. By using RECOLL\_EXTRA\_DBS and
-RECOLL\_ACTIVE\_EXTRA\_DBS, you can add and activate the index for the
-mounted volume when starting ``recoll``.
-
-RECOLL\_ACTIVE\_EXTRA\_DBS is available for RCL versions 1.17.2 and
-later. A change was made in the same update so that ``recoll`` will
-automatically deactivate unreachable indexes when starting up.
-
-Document history
-~~~~~~~~~~~~~~~~
-
-Documents that you actually view (with the internal preview or an
-external tool) are entered into the document history, which is
-remembered.
-
-You can display the history list by using the Tools/Doc History menu
-entry.
-
-You can erase the document history by using the Erase document history
-entry in the File menu.
-
-Sorting search results and collapsing duplicates
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The documents in a result list are normally sorted in order of
-relevance. It is possible to specify a different sort order, either by
-using the vertical arrows in the GUI toolbox to sort by date, or
-switching to the result table display and clicking on any header. The
-sort order chosen inside the result table remains active if you switch
-back to the result list, until you click one of the vertical arrows,
-until both are unchecked (you are back to sort by relevance).
-
-Sort parameters are remembered between program invocations, but result
-sorting is normally always inactive when the program starts. It is
-possible to keep the sorting activation state between program
-invocations by checking the Remember sort activation state option in the
-preferences.
-
-It is also possible to hide duplicate entries inside the result list
-(documents with the exact same contents as the displayed one). The test
-of identity is based on an MD5 hash of the document container, not only
-of the text contents (so that ie, a text document with an image added
-will not be a duplicate of the text only). Duplicates hiding is
-controlled by an entry in the GUI configuration dialog, and is off by
-default.
-
-As of release 1.19, when a result document does have undisplayed
-duplicates, a ``Dups`` link will be shown with the result list entry.
-Clicking the link will display the paths (URLs + ipaths) for the
-duplicate entries.
-
-Search tips, shortcuts
-~~~~~~~~~~~~~~~~~~~~~~
-
-Terms and search expansion
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-**Term completion.**
-
-Typing Esc Space in the simple search entry field while entering a word
-will either complete the current word if its beginning matches a unique
-term in the index, or open a window to propose a list of completions.
-
-**Picking up new terms from result or preview text.**
-
-Double-clicking on a word in the result list or in a preview window will
-copy it to the simple search entry field.
-
-**Wildcards.**
-
-Wildcards can be used inside search terms in all forms of searches.
-`More about wildcards <#RCL.SEARCH.WILDCARDS>`__.
-
-**Automatic suffixes.**
-
-Words like ``odt`` or ``ods`` can be automatically turned into query
-language ``ext:xxx`` clauses. This can be enabled in the Search
-preferences panel in the GUI.
-
-**Disabling stem expansion.**
-
-Entering a capitalized word in any search field will prevent stem
-expansion (no search for ``gardening`` if you enter ``Garden`` instead
-of ``garden``). This is the only case where character case should make a
-difference for a RCL search. You can also disable stem expansion or
-change the stemming language in the preferences.
-
-**Finding related documents.**
-
-Selecting the Find similar documents entry in the result list paragraph
-right-click menu will select a set of "interesting" terms from the
-current result, and insert them into the simple search entry field. You
-can then possibly edit the list and start a search to find documents
-which may be apparented to the current result.
-
-**File names.**
-
-File names are added as terms during indexing, and you can specify them
-as ordinary terms in normal search fields (RCL used to index all
-directories in the file path as terms. This has been abandoned as it did
-not seem really useful). Alternatively, you can use the specific file
-name search which will *only* look for file names, and may be faster
-than the generic search especially when using wildcards.
-
-Working with phrases and proximity
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-**Phrases and Proximity searches.**
-
-A phrase can be looked for by enclosing it in double quotes. Example:
-``"user manual"`` will look only for occurrences of ``user`` immediately
-followed by ``manual``. You can use the This phrase field of the
-advanced search dialog to the same effect. Phrases can be entered along
-simple terms in all simple or advanced search entry fields (except This
-exact phrase).
-
-**AutoPhrases.**
-
-This option can be set in the preferences dialog. If it is set, a phrase
-will be automatically built and added to simple searches when looking
-for ``Any terms``. This will not change radically the results, but will
-give a relevance boost to the results where the search terms appear as a
-phrase. Ie: searching for ``virtual reality`` will still find all
-documents where either ``virtual`` or ``reality`` or both appear, but
-those which contain ``virtual reality`` should appear sooner in the
-list.
-
-Phrase searches can strongly slow down a query if most of the terms in
-the phrase are common. This is why the ``autophrase`` option is off by
-default for RCL versions before 1.17. As of version 1.17, ``autophrase``
-is on by default, but very common terms will be removed from the
-constructed phrase. The removal threshold can be adjusted from the
-search preferences.
-
-**Phrases and abbreviations.**
-
-As of RCL version 1.17, dotted abbreviations like ``I.B.M.`` are also
-automatically indexed as a word without the dots: ``IBM``. Searching for
-the word inside a phrase (ie: ``"the IBM company"``) will only match the
-dotted abrreviation if you increase the phrase slack (using the advanced
-search panel control, or the ``o`` query language modifier). Literal
-occurences of the word will be matched normally.
-
-Others
-^^^^^^
-
-**Using fields.**
-
-You can use the `query language <#RCL.SEARCH.LANG>`__ and field
-specifications to only search certain parts of documents. This can be
-especially helpful with email, for example only searching emails from a
-specific originator: ``search tips from:helpfulgui``
-
-**Ajusting the result table columns.**
-
-When displaying results in table mode, you can use a right click on the
-table headers to activate a pop-up menu which will let you adjust what
-columns are displayed. You can drag the column headers to adjust their
-order. You can click them to sort by the field displayed in the column.
-You can also save the result list in CSV format.
-
-**Changing the GUI geometry.**
-
-It is possible to configure the GUI in wide form factor by dragging the
-toolbars to one of the sides (their location is remembered between
-sessions), and moving the category filters to a menu (can be set in the
-Preferences > GUI configuration > User interface panel).
-
-**Query explanation.**
-
-You can get an exact description of what the query looked for, including
-stem expansion, and Boolean operators used, by clicking on the result
-list header.
-
-**Advanced search history.**
-
-As of RCL 1.18, you can display any of the last 100 complex searches
-performed by using the up and down arrow keys while the advanced search
-panel is active.
-
-**Browsing the result list inside a preview window.**
-
-Entering Shift-Down or Shift-Up (Shift + an arrow key) in a preview
-window will display the next or the previous document from the result
-list. Any secondary search currently active will be executed on the new
-document.
-
-**Scrolling the result list from the keyboard.**
-
-You can use PageUp and PageDown to scroll the result list, Shift+Home to
-go back to the first page. These work even while the focus is in the
-search entry.
-
-**Result table: moving the focus to the table.**
-
-You can use Ctrl-r to move the focus from the search entry to the table,
-and then use the arrow keys to change the current row. Ctrl-Shift-s
-returns to the search.
-
-**Result table: open / preview.**
-
-With the focus in the result table, you can use Ctrl-o to open the
-document from the current row, Ctrl-Shift-o to open the document and
-close ``recoll``, Ctrl-d to preview the document.
-
-**Editing a new search while the focus is not in the search entry.**
-
-You can use the Ctrl-Shift-S shortcut to return the cursor to the search
-entry (and select the current search text), while the focus is anywhere
-in the main window.
-
-**Forced opening of a preview window.**
-
-You can use Shift+Click on a result list ``Preview`` link to force the
-creation of a preview window instead of a new tab in the existing one.
-
-**Closing previews.**
-
-Entering Ctrl-W in a tab will close it (and, for the last tab, close the
-preview window). Entering Esc will close the preview window and all its
-tabs.
-
-**Printing previews.**
-
-Entering Ctrl-P in a preview window will print the currently displayed
-text.
-
-**Quitting.**
-
-Entering Ctrl-Q almost anywhere will close the application.
-
-Saving and restoring queries (1.21 and later)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Both simple and advanced query dialogs save recent history, but the
-amount is limited: old queries will eventually be forgotten. Also,
-important queries may be difficult to find among others. This is why
-both types of queries can also be explicitely saved to files, from the
-GUI menus: File > Save last query / Load last query
-
-The default location for saved queries is a subdirectory of the current
-configuration directory, but saved queries are ordinary files and can be
-written or moved anywhere.
-
-Some of the saved query parameters are part of the preferences (e.g.
-``autophrase`` or the active external indexes), and may differ when the
-query is loaded from the time it was saved. In this case, RCL will warn
-of the differences, but will not change the user preferences.
-
-Customizing the search interface
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-You can customize some aspects of the search interface by using the GUI
-configuration entry in the Preferences menu.
-
-There are several tabs in the dialog, dealing with the interface itself,
-the parameters used for searching and returning results, and what
-indexes are searched.
-
-**User interface parameters:.**
-
--  Highlight color for query terms: Terms from the user query are
-   highlighted in the result list samples and the preview window. The
-   color can be chosen here. Any Qt color string should work (ie
-   ``red``, ``#ff0000``). The default is ``blue``.
-
--  Style sheet: The name of a Qt style sheet text file which is applied
-   to the whole Recoll application on startup. The default value is
-   empty, but there is a skeleton style sheet (``recoll.qss``) inside
-   the ``/usr/share/recoll/examples`` directory. Using a style sheet,
-   you can change most ``recoll`` graphical parameters: colors, fonts,
-   etc. See the sample file for a few simple examples.
-
-   You should be aware that parameters (e.g.: the background color) set
-   inside the RCL GUI style sheet will override global system
-   preferences, with possible strange side effects: for example if you
-   set the foreground to a light color and the background to a dark one
-   in the desktop preferences, but only the background is set inside the
-   RCL style sheet, and it is light too, then text will appear
-   light-on-light inside the RCL GUI.
-
--  Maximum text size highlighted for preview Inserting highlights on
-   search term inside the text before inserting it in the preview window
-   involves quite a lot of processing, and can be disabled over the
-   given text size to speed up loading.
-
--  Prefer HTML to plain text for preview if set, Recoll will display
-   HTML as such inside the preview window. If this causes problems with
-   the Qt HTML display, you can uncheck it to display the plain text
-   version instead.
-
--  Activate links in preview if set, Recoll will turn HTTP links found
-   inside plain text into proper HTML anchors, and clicking a link
-   inside a preview window will start the default browser on the link
-   target.
-
--  Plain text to HTML line style: when displaying plain text inside the
-   preview window, RCL tries to preserve some of the original text line
-   breaks and indentation. It can either use PRE HTML tags, which will
-   well preserve the indentation but will force horizontal scrolling for
-   long lines, or use BR tags to break at the original line breaks,
-   which will let the editor introduce other line breaks according to
-   the window width, but will lose some of the original indentation. The
-   third option has been available in recent releases and is probably
-   now the best one: use PRE tags with line wrapping.
-
--  Choose editor application: this opens a dialog which allows you to
-   select the application to be used to open each MIME type. The default
-   is to use the ``xdg-open`` utility, but you can use this dialog to
-   override it, setting exceptions for MIME types that will still be
-   opened according to RCL preferences. This is useful for passing
-   parameters like page numbers or search strings to applications that
-   support them (e.g. evince). This cannot be done with ``xdg-open``
-   which only supports passing one parameter.
-
--  Disable Qt autocompletion in search entry: this will disable the
-   completion popup. Il will only appear, and display the full history,
-   either if you enter only white space in the search area, or if you
-   click the clock button on the right of the area.
-
--  Document filter choice style: this will let you choose if the
-   document categories are displayed as a list or a set of buttons, or a
-   menu.
-
--  Start with simple search mode: this lets you choose the value of the
-   simple search type on program startup. Either a fixed value (e.g.
-   ``Query Language``, or the value in use when the program last exited.
-
--  Start with advanced search dialog open: If you use this dialog
-   frequently, checking the entries will get it to open when recoll
-   starts.
-
--  Remember sort activation state if set, Recoll will remember the sort
-   tool stat between invocations. It normally starts with sorting
-   disabled.
-
-**Result list parameters:.**
-
--  Number of results in a result page
-
--  Result list font: There is quite a lot of information shown in the
-   result list, and you may want to customize the font and/or font size.
-   The rest of the fonts used by RCL are determined by your generic Qt
-   config (try the ``qtconfig`` command).
-
--  Edit result list paragraph format string: allows you to change the
-   presentation of each result list entry. See the `result list
-   customisation section <#RCL.SEARCH.GUI.CUSTOM.RESLIST>`__.
-
--  Edit result page HTML header insert: allows you to define text
-   inserted at the end of the result page HTML header. More detail in
-   the `result list customisation
-   section. <#RCL.SEARCH.GUI.CUSTOM.RESLIST>`__
-
--  Date format: allows specifying the format used for displaying dates
-   inside the result list. This should be specified as an strftime()
-   string (man strftime).
-
--  Abstract snippet separator: for synthetic abstracts built from index
-   data, which are usually made of several snippets from different parts
-   of the document, this defines the snippet separator, an ellipsis by
-   default.
-
-**Search parameters:.**
-
--  Hide duplicate results: decides if result list entries are shown for
-   identical documents found in different places.
-
--  Stemming language: stemming obviously depends on the document's
-   language. This listbox will let you chose among the stemming
-   databases which were built during indexing (this is set in the `main
-   configuration file <#RCL.INSTALL.CONFIG.RECOLLCONF>`__), or later
-   added with ``recollindex -s`` (See the recollindex manual). Stemming
-   languages which are dynamically added will be deleted at the next
-   indexing pass unless they are also added in the configuration file.
-
--  Automatically add phrase to simple searches: a phrase will be
-   automatically built and added to simple searches when looking for
-   ``Any terms``. This will give a relevance boost to the results where
-   the search terms appear as a phrase (consecutive and in order).
-
--  Autophrase term frequency threshold percentage: very frequent terms
-   should not be included in automatic phrase searches for performance
-   reasons. The parameter defines the cutoff percentage (percentage of
-   the documents where the term appears).
-
--  Replace abstracts from documents: this decides if we should
-   synthesize and display an abstract in place of an explicit abstract
-   found within the document itself.
-
--  Dynamically build abstracts: this decides if RCL tries to build
-   document abstracts (lists of *snippets*) when displaying the result
-   list. Abstracts are constructed by taking context from the document
-   information, around the search terms.
-
--  Synthetic abstract size: adjust to taste...
-
--  Synthetic abstract context words: how many words should be displayed
-   around each term occurrence.
-
--  Query language magic file name suffixes: a list of words which
-   automatically get turned into ``ext:xxx`` file name suffix clauses
-   when starting a query language query (e.g.: ``doc xls xlsx...``).
-   This will save some typing for people who use file types a lot when
-   querying.
-
-**External indexes:.**
-
-This panel will let you browse for additional indexes that you may want
-to search. External indexes are designated by their database directory
-(ie: ``/home/someothergui/.recoll/xapiandb``,
-``/usr/local/recollglobal/xapiandb``).
-
-Once entered, the indexes will appear in the External indexes list, and
-you can chose which ones you want to use at any moment by checking or
-unchecking their entries.
-
-Your main database (the one the current configuration indexes to), is
-always implicitly active. If this is not desirable, you can set up your
-configuration so that it indexes, for example, an empty directory. An
-alternative indexer may also need to implement a way of purging the
-index from stale data,
-
-The result list format
-^^^^^^^^^^^^^^^^^^^^^^
-
-Newer versions of Recoll (from 1.17) normally use WebKit HTML widgets
-for the result list and the `snippets
-window <#RCL.SEARCH.GUI.RESULTLIST.MENU.SNIPPETS>`__ (this may be
-disabled at build time). Total customisation is possible with full
-support for CSS and Javascript. Conversely, there are limits to what you
-can do with the older Qt QTextBrowser, but still, it is possible to
-decide what data each result will contain, and how it will be displayed.
-
-The result list presentation can be exhaustively customized by adjusting
-two elements:
-
--  The paragraph format
-
--  HTML code inside the header section. For versions 1.21 and later,
-   this is also used for the `snippets
-   window <#RCL.SEARCH.GUI.RESULTLIST.MENU.SNIPPETS>`__
-
-The paragraph format and the header fragment can be edited from the
-Result list tab of the GUI configuration.
-
-The header fragment is used both for the result list and the snippets
-window. The snippets list is a table and has a ``snippets`` class
-attribute. Each paragraph in the result list is a table, with class
-``respar``, but this can be changed by editing the paragraph format.
-
-There are a few examples on the `page about customising the result
-list `__ on the RCL web site.
-
-The paragraph format
-''''''''''''''''''''
-
-This is an arbitrary HTML string where the following printf-like ``%``
-substitutions will be performed:
-
--  **%A.**
-
-   Abstract
-
--  **%D.**
-
-   Date
-
--  **%I.**
-
-   Icon image name. This is normally determined from the MIME type. The
-   associations are defined inside the ```mimeconf`` configuration
-   file <#RCL.INSTALL.CONFIG.MIMECONF>`__. If a thumbnail for the file
-   is found at the standard Freedesktop location, this will be displayed
-   instead.
-
--  **%K.**
-
-   Keywords (if any)
-
--  **%L.**
-
-   Precooked Preview, Edit, and possibly Snippets links
-
--  **%M.**
-
-   MIME type
-
--  **%N.**
-
-   result Number inside the result page
-
--  **%P.**
-
-   Parent folder Url. In the case of an embedded document, this is the
-   parent folder for the top level container file.
-
--  **%R.**
-
-   Relevance percentage
-
--  **%S.**
-
-   Size information
-
--  **%T.**
-
-   Title or Filename if not set.
-
--  **%t.**
-
-   Title or empty.
-
--  **%(filename).**
-
-   File name.
-
--  **%U.**
-
-   Url
-
-The format of the Preview, Edit, and Snippets links is
-````, ```` and ```` where
-docnum (%N) expands to the document number inside the result page).
-
-A link target defined as ``"F%N"`` will open the document corresponding
-to the ``%P`` parent folder expansion, usually creating a file manager
-window on the folder where the container file resides. E.g.:
-
-::
-
-    %P
-
-A link target defined as ``R%N|scriptname`` will run the corresponding
-script on the result file (if the document is embedded, the script will
-be started on the top-level parent). See the `section about defining
-scripts <#RCL.SEARCH.GUI.RUNSCRIPT>`__.
-
-In addition to the predefined values above, all strings like
-``%(fieldname)`` will be replaced by the value of the field named
-``fieldname`` for this document. Only stored fields can be accessed in
-this way, the value of indexed but not stored fields is not known at
-this point in the search process (see `field
-configuration <#RCL.PROGRAM.FIELDS>`__). There are currently very few
-fields stored by default, apart from the values above (only ``author``
-and ``filename``), so this feature will need some custom local
-configuration to be useful. An example candidate would be the
-``recipient`` field which is generated by the message input handlers.
-
-The default value for the paragraph format string is:
-
-::
-
-                "\n"
-                "\n"
-                "\n"
-                "\n"
-                "
%L  %S   %T
\n" - "%M %D    %U %i
\n" - "%A %K
\n" - - -You may, for example, try the following for a more web-like experience: - -:: - - %T
- %A%U - %S - %L - - -Note that the P%N link in the above paragraph makes the title a preview -link. Or the clean looking: - -:: - - %L %R -   %T&
%S  - %U - - -
%A
%K - - -These samples, and some others are `on the web site, with pictures to -show how they look. `__ - -It is also possible to `define the value of the snippet separator inside -the abstract section <#RCL.SEARCH.GUI.CUSTOM.ABSSEP>`__. - -Searching with the KDE KIO slave --------------------------------- - -What's this -~~~~~~~~~~~ - -The RCL KIO slave allows performing a RCL search by entering an -appropriate URL in a KDE open dialog, or with an HTML-based interface -displayed in ``Konqueror``. - -The HTML-based interface is similar to the Qt-based interface, but -slightly less powerful for now. Its advantage is that you can perform -your search while staying fully within the KDE framework: drag and drop -from the result list works normally and you have your normal choice of -applications for opening files. - -The alternative interface uses a directory view of search results. Due -to limitations in the current KIO slave interface, it is currently not -obviously useful (to me). - -The interface is described in more detail inside a help file which you -can access by entering ``recoll:/`` inside the ``konqueror`` URL line -(this works only if the recoll KIO slave has been previously installed). - -The instructions for building this module are located in the source -tree. See: ``kde/kio/recoll/00README.txt``. Some Linux distributions do -package the kio-recoll module, so check before diving into the build -process, maybe it's already out there ready for one-click installation. - -Searchable documents -~~~~~~~~~~~~~~~~~~~~ - -As a sample application, the RCL KIO slave could allow preparing a set -of HTML documents (for example a manual) so that they become their own -search interface inside ``konqueror``. - -This can be done by either explicitly inserting -```` links around some document areas, or -automatically by adding a very small javascript program to the -documents, like the following example, which would initiate a search by -double-clicking any term: - -:: - - - .... - - - - -Searching on the command line ------------------------------ - -There are several ways to obtain search results as a text stream, -without a graphical interface: - -- By passing option ``-t`` to the ``recoll`` program, or by calling it - as ``recollq`` (through a link). - -- By using the ``recollq`` program. - -- By writing a custom Python program, using the `Recoll Python - API <#RCL.PROGRAM.PYTHONAPI>`__. - -The first two methods work in the same way and accept/need the same -arguments (except for the additional ``-t`` to ``recoll``). The query to -be executed is specified as command line arguments. - -``recollq`` is not built by default. You can use the ``Makefile`` in the -``query`` directory to build it. This is a very simple program, and if -you can program a little c++, you may find it useful to taylor its -output format to your needs. Not that recollq is only really useful on -systems where the Qt libraries (or even the X11 ones) are not available. -Otherwise, just use ``recoll -t``, which takes the exact same parameters -and options which are described for ``recollq`` - -``recollq`` has a man page (not installed by default, look in the -``doc/man`` directory). The Usage string is as follows: - -:: - - recollq: usage: - -P: Show the date span for all the documents present in the index - [-o|-a|-f] [-q] - Runs a recoll query and displays result lines. - Default: will interpret the argument(s) as a xesam query string - query may be like: - implicit AND, Exclusion, field spec: t1 -t2 title:t3 - OR has priority: t1 OR t2 t3 OR t4 means (t1 OR t2) AND (t3 OR t4) - Phrase: "t1 t2" (needs additional quoting on cmd line) - -o Emulate the GUI simple search in ANY TERM mode - -a Emulate the GUI simple search in ALL TERMS mode - -f Emulate the GUI simple search in filename mode - -q is just ignored (compatibility with the recoll GUI command line) - Common options: - -c : specify config directory, overriding $RECOLL_CONFDIR - -d also dump file contents - -n [first-] define the result slice. The default value for [first] - is 0. Without the option, the default max count is 2000. - Use n=0 for no limit - -b : basic. Just output urls, no mime types or titles - -Q : no result lines, just the processed query and result count - -m : dump the whole document meta[] array for each result - -A : output the document abstracts - -S fld : sort by field - -s stemlang : set stemming language to use (must exist in index...) - Use -s "" to turn off stem expansion - -D : sort descending - -i : additional index, several can be given - -e use url encoding (%xx) for urls - -F : output exactly these fields for each result. - The field values are encoded in base64, output in one line and - separated by one space character. This is the recommended format - for use by other programs. Use a normal query with option -m to - see the field names. - - -Sample execution: - -:: - - recollq 'ilur -nautique mime:text/html' - Recoll query: ((((ilur:(wqf=11) OR ilurs) AND_NOT (nautique:(wqf=11) - OR nautiques OR nautiqu OR nautiquement)) FILTER Ttext/html)) - 4 results - text/html [file:///Users/uncrypted-dockes/projets/bateaux/ilur/comptes.html] [comptes.html] 18593 bytes - text/html [file:///Users/uncrypted-dockes/projets/nautique/webnautique/articles/ilur1/index.html] [Constructio... - text/html [file:///Users/uncrypted-dockes/projets/pagepers/index.html] [psxtcl/writemime/recoll]... - text/html [file:///Users/uncrypted-dockes/projets/bateaux/ilur/factEtCie/recu-chasse-maree.... - - -Using Synonyms (1.22) ---------------------- - -**Term synonyms:.** - -there are a number of ways to use term synonyms for searching text: - -- At index creation time, they can be used to alter the indexed terms, - either increasing or decreasing their number, by expanding the - original terms to all synonyms, or by reducing all synonym terms to a - canonical one. - -- At query time, they can be used to match texts containing terms which - are synonyms of the ones specified by the user, either by expanding - the query for all synonyms, or by reducing the user entry to - canonical terms (the latter only works if the corresponding - processing has been performed while creating the index). - -RCL only uses synonyms at query time. A user query term which part of a -synonym group will be optionally expanded into an ``OR`` query for all -terms in the group. - -Synonym groups are defined inside ordinary text files. Each line in the -file defines a group. - -Example: - -:: - - hi hello "good morning" - - # not sure about "au revoir" though. Is this english ? - bye goodbye "see you" \ - "au revoir" - - -As usual, lines beginning with a ``#`` are comments, empty lines are -ignored, and lines can be continued by ending them with a backslash. - -Multi-word synonyms are supported, but be aware that these will generate -phrase queries, which may degrade performance and will disable stemming -expansion for the phrase terms. - -The synonyms file can be specified in the Search parameters tab of the -GUI configuration Preferences menu entry, or as an option for -command-line searches. - -Once the file is defined, the use of synonyms can be enabled or disabled -directly from the Preferences menu. - -The synonyms are searched for matches with user terms after the latter -are stem-expanded, but the contents of the synonyms file itself is not -subjected to stem expansion. This means that a match will not be found -if the form present in the synonyms file is not present anywhere in the -document set. - -The synonyms function is probably not going to help you find your -letters to Mr. Smith. It is best used for domain-specific searches. For -example, it was initially suggested by a user performing searches among -historical documents: the synonyms file would contains nicknames and -aliases for each of the persons of interest. - -Path translations ------------------ - -In some cases, the document paths stored inside the index do not match -the actual ones, so that document previews and accesses will fail. This -can occur in a number of circumstances: - -- When using multiple indexes it is a relatively common occurrence that - some will actually reside on a remote volume, for exemple mounted via - NFS. In this case, the paths used to access the documents on the - local machine are not necessarily the same than the ones used while - indexing on the remote machine. For example, ``/home/me`` may have - been used as a ``topdirs`` elements while indexing, but the directory - might be mounted as ``/net/server/home/me`` on the local machine. - -- The case may also occur with removable disks. It is perfectly - possible to configure an index to live with the documents on the - removable disk, but it may happen that the disk is not mounted at the - same place so that the documents paths from the index are invalid. - -- As a last exemple, one could imagine that a big directory has been - moved, but that it is currently inconvenient to run the indexer. - -RCL has a facility for rewriting access paths when extracting the data -from the index. The translations can be defined for the main index and -for any additional query index. - -The path translation facility will be useful whenever the documents -paths seen by the indexer are not the same as the ones which should be -used at query time. - -In the above NFS example, RCL could be instructed to rewrite any -``file:///home/me`` URL from the index to -``file:///net/server/home/me``, allowing accesses from the client. - -The translations are defined in the -```ptrans`` <#RCL.INSTALL.CONFIG.PTRANS>`__ configuration file, which -can be edited by hand or from the GUI external indexes configuration -dialog: Preferences > External index dialog, then click the Paths -translations button on the right below the index list. - - **Note** - - Due to a current bug, the GUI must be restarted after changing the - ``ptrans`` values (even when they were changed from the GUI). - -The query language ------------------- - -The query language processor is activated in the GUI simple search entry -when the search mode selector is set to Query Language. It can also be -used with the KIO slave or the command line search. It broadly has the -same capabilities as the complex search interface in the GUI. - -The language was based on the now defunct -`Xesam `__ user -search language specification. - -If the results of a query language search puzzle you and you doubt what -has been actually searched for, you can use the GUI ``Show Query`` link -at the top of the result list to check the exact query which was finally -executed by Xapian. - -Here follows a sample request that we are going to explain: - -:: - - author:"john doe" Beatles OR Lennon Live OR Unplugged -potatoes - - -This would search for all documents with John Doe appearing as a phrase -in the author field (exactly what this is would depend on the document -type, ie: the ``From:`` header, for an email message), and containing -either beatles or lennon and either live or unplugged but not potatoes -(in any part of the document). - -An element is composed of an optional field specification, and a value, -separated by a colon (the field separator is the last colon in the -element). Examples: Eugenie, author:balzac, dc:title:grandet -dc:title:"eugenie grandet" - -The colon, if present, means "contains". Xesam defines other relations, -which are mostly unsupported for now (except in special cases, described -further down). - -All elements in the search entry are normally combined with an implicit -AND. It is possible to specify that elements be OR'ed instead, as in -Beatles ``OR`` Lennon. The ``OR`` must be entered literally (capitals), -and it has priority over the AND associations: word1 word2 ``OR`` word3 -means word1 AND (word2 ``OR`` word3) not (word1 AND word2) ``OR`` word3. - -RCL versions 1.21 and later, allow using parentheses to group elements, -which will sometimes make things clearer, and may allow expressing -combinations which would have been difficult otherwise. - -An element preceded by a ``-`` specifies a term that should *not* -appear. - -As usual, words inside quotes define a phrase (the order of words is -significant), so that title:"prejudice pride" is not the same as -title:prejudice title:pride, and is unlikely to find a result. - -Words inside phrases and capitalized words are not stem-expanded. -Wildcards may be used anywhere inside a term. Specifying a wild-card on -the left of a term can produce a very slow search (or even an incorrect -one if the expansion is truncated because of excessive size). Also see -`More about wildcards <#RCL.SEARCH.WILDCARDS>`__. - -To save you some typing, recent RCL versions (1.20 and later) interpret -a comma-separated list of terms as an AND list inside the field. Use -slash characters ('/') for an OR list. No white space is allowed. So - -:: - - author:john,lennon - -will search for documents with ``john`` and ``lennon`` inside the -``author`` field (in any order), and - -:: - - author:john/ringo - -would search for ``john`` or ``ringo``. - -Modifiers can be set on a double-quote value, for example to specify a -proximity search (unordered). See `the modifier -section <#RCL.SEARCH.LANG.MODIFIERS>`__. No space must separate the -final double-quote and the modifiers value, e.g. "two one"po10 - -RCL currently manages the following default fields: - -- ``title``, ``subject`` or ``caption`` are synonyms which specify data - to be searched for in the document title or subject. - -- ``author`` or ``from`` for searching the documents originators. - -- ``recipient`` or ``to`` for searching the documents recipients. - -- ``keyword`` for searching the document-specified keywords (few - documents actually have any). - -- ``filename`` for the document's file name. This is not necessarily - set for all documents: internal documents contained inside a compound - one (for example an EPUB section) do not inherit the container file - name any more, this was replaced by an explicit field (see next). - Sub-documents can still have a specific ``filename``, if it is - implied by the document format, for example the attachment file name - for an email attachment. - -- ``containerfilename``. This is set for all documents, both top-level - and contained sub-documents, and is always the name of the filesystem - directory entry which contains the data. The terms from this field - can only be matched by an explicit field specification (as opposed to - terms from ``filename`` which are also indexed as general document - content). This avoids getting matches for all the sub-documents when - searching for the container file name. - -- ``ext`` specifies the file name extension (Ex: ``ext:html``) - -RCL 1.20 and later have a way to specify aliases for the field names, -which will save typing, for example by aliasing ``filename`` to fn or -``containerfilename`` to cfn. See the `section about the ``fields`` -file <#RCL.INSTALL.CONFIG.FIELDS>`__ - -The document input handlers used while indexing have the possibility to -create other fields with arbitrary names, and aliases may be defined in -the configuration, so that the exact field search possibilities may be -different for you if someone took care of the customisation. - -The field syntax also supports a few field-like, but special, criteria: - -- ``dir`` for filtering the results on file location (Ex: - ``dir:/home/me/somedir``). ``-dir`` also works to find results not in - the specified directory (release >= 1.15.8). Tilde expansion will be - performed as usual (except for a bug in versions 1.19 to 1.19.11p1). - Wildcards will be expanded, but please `have a - look <#RCL.SEARCH.WILDCARDS.PATH>`__ at an important limitation of - wildcards in path filters. - - Relative paths also make sense, for example, ``dir:share/doc`` would - match either ``/usr/share/doc`` or ``/usr/local/share/doc`` - - Several ``dir`` clauses can be specified, both positive and negative. - For example the following makes sense: - - :: - - dir:recoll dir:src -dir:utils -dir:common - - - This would select results which have both ``recoll`` and ``src`` in - the path (in any order), and which have not either ``utils`` or - ``common``. - - You can also use ``OR`` conjunctions with ``dir:`` clauses. - - A special aspect of ``dir`` clauses is that the values in the index - are not transcoded to UTF-8, and never lower-cased or unaccented, but - stored as binary. This means that you need to enter the values in the - exact lower or upper case, and that searches for names with - diacritics may sometimes be impossible because of character set - conversion issues. Non-ASCII UNIX file paths are an unending source - of trouble and are best avoided. - - You need to use double-quotes around the path value if it contains - space characters. - -- ``size`` for filtering the results on file size. Example: - ``size<10000``. You can use ``<``, ``>`` or ``=`` as operators. You - can specify a range like the following: ``size>100 size<1000``. The - usual ``k/K, m/M, g/G, t/T`` can be used as (decimal) multipliers. - Ex: ``size>1k`` to search for files bigger than 1000 bytes. - -- ``date`` for searching or filtering on dates. The syntax for the - argument is based on the ISO8601 standard for dates and time - intervals. Only dates are supported, no times. The general syntax is - 2 elements separated by a ``/`` character. Each element can be a date - or a period of time. Periods are specified as - ``P``\ n\ ``Y``\ n\ ``M``\ n\ ``D``. The n numbers are the respective - numbers of years, months or days, any of which may be missing. Dates - are specified as YYYY-MM-DD. The days and months parts may be - missing. If the ``/`` is present but an element is missing, the - missing element is interpreted as the lowest or highest date in the - index. Examples: - - - ``2001-03-01/2002-05-01`` the basic syntax for an interval of - dates. - - - ``2001-03-01/P1Y2M`` the same specified with a period. - - - ``2001/`` from the beginning of 2001 to the latest date in the - index. - - - ``2001`` the whole year of 2001 - - - ``P2D/`` means 2 days ago up to now if there are no documents with - dates in the future. - - - ``/2003`` all documents from 2003 or older. - - Periods can also be specified with small letters (ie: p2y). - -- ``mime`` or ``format`` for specifying the MIME type. These clauses - are processed besides the normal Boolean logic of the search. - Multiple values will be OR'ed (instead of the normal AND). You can - specify types to be excluded, with the usual ``-``, and use - wildcards. Example: mime:text/\* -mime:text/plain Specifying an - explicit boolean operator before a ``mime`` specification is not - supported and will produce strange results. - -- ``type`` or ``rclcat`` for specifying the category (as in - text/media/presentation/etc.). The classification of MIME types in - categories is defined in the RCL configuration (``mimeconf``), and - can be modified or extended. The default category names are those - which permit filtering results in the main GUI screen. Categories are - OR'ed like MIME types above, and can be negated with ``-``. - - **Note** - - ``mime``, ``rclcat``, ``size`` and ``date`` criteria always affect - the whole query (they are applied as a final filter), even if set - with other terms inside a parenthese. - - **Note** - - ``mime`` (or the equivalent ``rclcat``) is the *only* field with an - ``OR`` default. You do need to use ``OR`` with ``ext`` terms for - example. - -Range clauses -~~~~~~~~~~~~~ - -RCL 1.24 and later support range clauses on fields which have been -configured to support it. No default field uses them currently, so this -paragraph is only interesting if you modified the fields configuration -and possibly use a custom input handler. - -A range clause looks like one of the following: - -:: - - myfield:small..big - myfield:small.. - myfield:..big - - -The nature of the clause is indicated by the two dots ``..``, and the -effect is to filter the results for which the myfield value is in the -possibly open-ended interval. - -See the section about the ```fields`` configuration -file <#RCL.INSTALL.CONFIG.FIELDS>`__ for the details of configuring a -field for range searches (list them in the [values] section). - -Modifiers -~~~~~~~~~ - -Some characters are recognized as search modifiers when found -immediately after the closing double quote of a phrase, as in -``"some term"modifierchars``. The actual "phrase" can be a single term -of course. Supported modifiers: - -- ``l`` can be used to turn off stemming (mostly makes sense with ``p`` - because stemming is off by default for phrases). - -- ``s`` can be used to turn off synonym expansion, if a synonyms file - is in place (only for RCL 1.22 and later). - -- ``o`` can be used to specify a "slack" for phrase and proximity - searches: the number of additional terms that may be found between - the specified ones. If ``o`` is followed by an integer number, this - is the slack, else the default is 10. - -- ``p`` can be used to turn the default phrase search into a proximity - one (unordered). Example: ``"order any in"p`` - -- ``C`` will turn on case sensitivity (if the index supports it). - -- ``D`` will turn on diacritics sensitivity (if the index supports it). - -- A weight can be specified for a query element by specifying a decimal - value at the start of the modifiers. Example: ``"Important"2.5``. - -Search case and diacritics sensitivity --------------------------------------- - -For RCL versions 1.18 and later, and *when working with a raw index* -(not the default), searches can be sensitive to character case and -diacritics. How this happens is controlled by configuration variables -and what search data is entered. - -The general default is that searches entered without upper-case or -accented characters are insensitive to case and diacritics. An entry of -``resume`` will match any of ``Resume``, ``RESUME``, ``résumé``, -``Résumé`` etc. - -Two configuration variables can automate switching on sensitivity (they -were documented but actually did nothing until RCL 1.22): - -autodiacsens - If this is set, search sensitivity to diacritics will be turned on - as soon as an accented character exists in a search term. When the - variable is set to true, ``resume`` will start a - diacritics-unsensitive search, but ``résumé`` will be matched - exactly. The default value is *false*. - -autocasesens - If this is set, search sensitivity to character case will be turned - on as soon as an upper-case character exists in a search term - *except for the first one*. When the variable is set to true, ``us`` - or ``Us`` will start a diacritics-unsensitive search, but ``US`` - will be matched exactly. The default value is *true* (contrary to - ``autodiacsens``). - -As in the past, capitalizing the first letter of a word will turn off -its stem expansion and have no effect on case-sensitivity. - -You can also explicitely activate case and diacritics sensitivity by -using modifiers with the query language. ``C`` will make the term -case-sensitive, and ``D`` will make it diacritics-sensitive. Examples: - -:: - - "us"C - - -will search for the term ``us`` exactly (``Us`` will not be a match). - -:: - - "resume"D - - -will search for the term ``resume`` exactly (``résumé`` will not be a -match). - -When either case or diacritics sensitivity is activated, stem expansion -is turned off. Having both does not make much sense. - -Anchored searches and wildcards -------------------------------- - -Some special characters are interpreted by RCL in search strings to -expand or specialize the search. Wildcards expand a root term in -controlled ways. Anchor characters can restrict a search to succeed only -if the match is found at or near the beginning of the document or one of -its fields. - -More about wildcards -~~~~~~~~~~~~~~~~~~~~ - -All words entered in RCL search fields will be processed for wildcard -expansion before the request is finally executed. - -The wildcard characters are: - -- ``*`` which matches 0 or more characters. - -- ``?`` which matches a single character. - -- ``[]`` which allow defining sets of characters to be matched (ex: - ``[``\ ``abc``\ ``]`` matches a single character which may be 'a' or - 'b' or 'c', ``[``\ ``0-9``\ ``]`` matches any number. - -You should be aware of a few things when using wildcards. - -- Using a wildcard character at the beginning of a word can make for a - slow search because RCL will have to scan the whole index term list - to find the matches. However, this is much less a problem for field - searches, and queries like author:\*@domain.com can sometimes be very - useful. - -- For RCL version 18 only, when working with a raw index (preserving - character case and diacritics), the literal part of a wildcard - expression will be matched exactly for case and diacritics. This is - not true any more for versions 19 and later. - -- Using a ``*`` at the end of a word can produce more matches than you - would think, and strange search results. You can use the `term - explorer <#RCL.SEARCH.GUI.TERMEXPLORER>`__ tool to check what - completions exist for a given term. You can also see exactly what - search was performed by clicking on the link at the top of the result - list. In general, for natural language terms, stem expansion will - produce better results than an ending ``*`` (stem expansion is turned - off when any wildcard character appears in the term). - -Wildcards and path filtering -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Due to the way that RCL processes wildcards inside ``dir`` path -filtering clauses, they will have a multiplicative effect on the query -size. A clause containg wildcards in several paths elements, like, for -example, ``dir:``/home/me/\*/\*/docdir, will almost certainly fail if -your indexed tree is of any realistic size. - -Depending on the case, you may be able to work around the issue by -specifying the paths elements more narrowly, with a constant prefix, or -by using 2 separate ``dir:`` clauses instead of multiple wildcards, as -in ``dir:``/home/me ``dir:``\ docdir. The latter query is not equivalent -to the initial one because it does not specify a number of directory -levels, but that's the best we can do (and it may be actually more -useful in some cases). - -Anchored searches -~~~~~~~~~~~~~~~~~ - -Two characters are used to specify that a search hit should occur at the -beginning or at the end of the text. ``^`` at the beginning of a term or -phrase constrains the search to happen at the start, ``$`` at the end -force it to happen at the end. - -As this function is implemented as a phrase search it is possible to -specify a maximum distance at which the hit should occur, either through -the controls of the advanced search panel, or using the query language, -for example, as in: - -:: - - "^someterm"o10 - -which would force ``someterm`` to be found within 10 terms of the start -of the text. This can be combined with a field search as in -``somefield:"^someterm"o10`` or ``somefield:someterm$``. - -This feature can also be used with an actual phrase search, but in this -case, the distance applies to the whole phrase and anchor, so that, for -example, ``bla bla my unexpected term`` at the beginning of the text -would be a match for ``"^my term"o5``. - -Anchored searches can be very useful for searches inside somewhat -structured documents like scientific articles, in case explicit metadata -has not been supplied (a most frequent case), for example for looking -for matches inside the abstract or the list of authors (which occur at -the top of the document). - -Desktop integration -------------------- - -Being independant of the desktop type has its drawbacks: RCL desktop -integration is minimal. However there are a few tools available: - -- The KDE KIO Slave was described in a `previous - section <#RCL.SEARCH.KIO>`__. - -- If you use a recent version of Ubuntu Linux, you may find the `Ubuntu - Unity Lens <&FAQS;UnityLens>`__ module useful. - -- There is also an independantly developed `Krunner - plugin `__. - -Here follow a few other things that may help. - -Hotkeying recoll -~~~~~~~~~~~~~~~~ - -It is surprisingly convenient to be able to show or hide the RCL GUI -with a single keystroke. Recoll comes with a small Python script, based -on the libwnck window manager interface library, which will allow you to -do just this. The detailed instructions are on `this wiki -page <&FAQS;HotRecoll>`__. - -The KDE Kicker Recoll applet -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This is probably obsolete now. Anyway: - -The RCL source tree contains the source code to the recoll\_applet, a -small application derived from the find\_applet. This can be used to add -a small RCL launcher to the KDE panel. - -The applet is not automatically built with the main RCL programs, nor is -it included with the main source distribution (because the KDE build -boilerplate makes it relatively big). You can download its source from -the recoll.org download page. Use the omnipotent -``configure;make;make install`` incantation to build and install. - -You can then add the applet to the panel by right-clicking the panel and -choosing the Add applet entry. - -The recoll\_applet has a small text window where you can type a RCL -query (in query language form), and an icon which can be used to -restrict the search to certain types of files. It is quite primitive, -and launches a new recoll GUI instance every time (even if it is already -running). You may find it useful anyway. - -Removable volumes -================= - -RCL used to have no support for indexing removable volumes (portable -disks, USB keys, etc.). Recent versions have improved the situation and -support indexing removable volumes in two different ways: - -- By storing a volume index on the volume itself (RCL 1.24). - -- By indexing the volume in the main, fixed, index, and ensuring that - the volume data is not purged if the indexing runs while the volume - is mounted. (RCL 1.25.2). - -Indexing removable volumes in the main index --------------------------------------------- - -As of version 1.25.2, RCL has a simple way to ensure that the index data -for an absent volume will not be purged: the volume mount point must be -a member of the ``topdirs`` list, and the mount directory must be empty -(when the volume is not mounted). If ``recollindex`` finds that one of -the ``topdirs`` is empty when starting up, any existing data for the -tree will be preserved by the indexing pass (no purge for this area). - -Self contained volumes ----------------------- - -As of RCL 1.24, it has become easy to build self-contained datasets -including a RCL configuration directory and index together with the -indexed documents, and to move such a dataset around (for example -copying it to an USB drive), without having to adjust the configuration -for querying the index. - - **Note** - - This is a query-time feature only. The index must only be updated in - its original location. If an update is necessary in a different - location, the index must be reset. - -To make a long story short, here follows a script to create a RCL -configuration and index under a given directory (given as single -parameter). The resulting data set (files + recoll directory) can later -to be moved to a CDROM or thumb drive. Longer explanations come after -the script. - -:: - - #!/bin/sh - - fatal() - { - echo $*;exit 1 - } - usage() - { - fatal "Usage: init-recoll-volume.sh " - } - - test $# = 1 || usage - topdir=$1 - test -d "$topdir" || fatal $topdir should be a directory - - confdir="$topdir/recoll-config" - test ! -d "$confdir" || fatal $confdir should not exist - - mkdir "$confdir" - cd "$topdir" - topdir=`pwd` - cd "$confdir" - confdir=`pwd` - - (echo topdirs = '"'$topdir'"'; \ - echo orgidxconfdir = $topdir/recoll-config) > "$confdir/recoll.conf" - - recollindex -c "$confdir" - -The examples below will assume that you have a dataset under -``/home/me/mydata/``, with the index configuration and data stored -inside ``/home/me/mydata/recoll-confdir``. - -In order to be able to run queries after the dataset has been moved, you -must ensure the following: - -- The main configuration file must define the - `orgidxconfdir <#RCL.INSTALL.CONFIG.RECOLLCONF.ORGIDXCONFDIR>`__ - variable to be the original location of the configuration directory - (``orgidxconfdir=/home/me/mydata/recoll-confdir`` must be set inside - ``/home/me/mydata/recoll-confdir/recoll.conf`` in the example above). - -- The configuration directory must exist with the documents, somewhere - under the directory which will be moved. E.g. if you are moving - ``/home/me/mydata`` around, the configuration directory must exist - somewhere below this point, for example - ``/home/me/mydata/recoll-confdir``, or - ``/home/me/mydata/sub/recoll-confdir``. - -- You should keep the default locations for the index elements (they - are relative to the configuration directory by default). Only the - paths referring to the documents themselves (e.g. ``topdirs`` values) - should be absolute (in general, they are only used when indexing - anyway). - -Only the first point needs an explicit user action, the RCL defaults are -compatible with the second one, and the third is natural. - -If, after the move, the configuration directory needs to be copied out -of the dataset (for example because the thumb drive is too slow), you -can set the -`curidxconfdir <#RCL.INSTALL.CONFIG.RECOLLCONF.CURIDXCONFDIR>`__, -variable inside the copied configuration to define the location of the -moved one. For example if ``/home/me/mydata`` is now mounted onto -``/media/me/somelabel``, but the configuration directory and index has -been copied to ``/tmp/tempconfig``, you would set ``curidxconfdir`` to -``/media/me/somelabel/recoll-confdir`` inside -``/tmp/tempconfig/recoll.conf``. ``orgidxconfdir`` would still be -``/home/me/mydata/recoll-confdir`` in the original and the copy. - -If you are regularly copying the configuration out of the dataset, it -will be useful to write a script to automate the procedure. This can't -really be done inside RCL because there are probably many possible -variants. One example would be to copy the configuration to make it -writable, but keep the index data on the medium because it is too big - -in this case, the script would also need to set ``dbdir`` in the copied -configuration. - -The same set of modifications (RCL 1.24) has also made it possible to -run queries from a readonly configuration directory (with slightly -reduced function of course, such as not recording the query history). - -Programming interface -===================== - -RCL has an Application Programming Interface, usable both for indexing -and searching, currently accessible from the Python language. - -Another less radical way to extend the application is to write input -handlers for new types of documents. - -The processing of metadata attributes for documents (``fields``) is -highly configurable. - -Writing a document input handler --------------------------------- - - **Note** - - The small programs or pieces of code which handle the processing of - the different document types for RCL used to be called ``filters``, - which is still reflected in the name of the directory which holds - them and many configuration variables. They were named this way - because one of their primary functions is to filter out the - formatting directives and keep the text content. However these - modules may have other behaviours, and the term ``input handler`` is - now progressively substituted in the documentation. ``filter`` is - still used in many places though. - -RCL input handlers cooperate to translate from the multitude of input -document formats, simple ones as opendocument, acrobat, or compound ones -such as Zip or Email, into the final RCL indexing input format, which is -plain text (in many cases the processing pipeline has an intermediary -HTML step, which may be used for better previewing presentation). Most -input handlers are executable programs or scripts. A few handlers are -coded in C++ and live inside ``recollindex``. This latter kind will not -be described here. - -There are currently (since version 1.13) two kinds of external -executable input handlers: - -- Simple ``exec`` handlers run once and exit. They can be bare programs - like ``antiword``, or scripts using other programs. They are very - simple to write, because they just need to print the converted - document to the standard output. Their output can be plain text or - HTML. HTML is usually preferred because it can store metadata fields - and it allows preserving some of the formatting for the GUI preview. - However, these handlers have limitations: - - - They can only process one document per file. - - - The output MIME type must be known and fixed. - - - The character encoding, if relevant, must be known and fixed (or - possibly just depending on location). - -- Multiple ``execm`` handlers can process multiple files (sparing the - process startup time which can be very significant), or multiple - documents per file (e.g.: for archives or multi-chapter - publications). They communicate with the indexer through a simple - protocol, but are nevertheless a bit more complicated than the older - kind. Most of the new handlers are written in Python (exception: - ``rclimg`` which is written in Perl because ``exiftool`` has no real - Python equivalent). The Python handlers use common modules to factor - out the boilerplate, which can make them very simple in favorable - cases. The subdocuments output by these handlers can be directly - indexable (text or HTML), or they can be other simple or compound - documents that will need to be processed by another handler. - -In both cases, handlers deal with regular file system files, and can -process either a single document, or a linear list of documents in each -file. RCL is responsible for performing up to date checks, deal with -more complex embedding and other upper level issues. - -A simple handler returning a document in ``text/plain`` format, can -transfer no metadata to the indexer. Generic metadata, like document -size or modification date, will be gathered and stored by the indexer. - -Handlers that produce ``text/html`` format can return an arbitrary -amount of metadata inside HTML ``meta`` tags. These will be processed -according to the directives found in the ```fields`` configuration -file <#RCL.PROGRAM.FIELDS>`__. - -The handlers that can handle multiple documents per file return a single -piece of data to identify each document inside the file. This piece of -data, called an ``ipath`` will be sent back by RCL to extract the -document at query time, for previewing, or for creating a temporary file -to be opened by a viewer. These handlers can also return metadata either -as HTML ``meta`` tags, or as named data through the communication -protocol. - -The following section describes the simple handlers, and the next one -gives a few explanations about the ``execm`` ones. You could conceivably -write a simple handler with only the elements in the manual. This will -not be the case for the other ones, for which you will have to look at -the code. - -Simple input handlers -~~~~~~~~~~~~~~~~~~~~~ - -RCL simple handlers are usually shell-scripts, but this is in no way -necessary. Extracting the text from the native format is the difficult -part. Outputting the format expected by RCL is trivial. Happily enough, -most document formats have translators or text extractors which can be -called from the handler. In some cases the output of the translating -program is completely appropriate, and no intermediate shell-script is -needed. - -Input handlers are called with a single argument which is the source -file name. They should output the result to stdout. - -When writing a handler, you should decide if it will output plain text -or HTML. Plain text is simpler, but you will not be able to add metadata -or vary the output character encoding (this will be defined in a -configuration file). Additionally, some formatting may be easier to -preserve when previewing HTML. Actually the deciding factor is metadata: -RCL has a way to `extract metadata from the HTML header and use it for -field searches. <#RCL.PROGRAM.FILTERS.HTML>`__. - -The RECOLL\_FILTER\_FORPREVIEW environment variable (values ``yes``, -``no``) tells the handler if the operation is for indexing or -previewing. Some handlers use this to output a slightly different -format, for example stripping uninteresting repeated keywords (ie: -``Subject:`` for email) when indexing. This is not essential. - -You should look at one of the simple handlers, for example ``rclps`` for -a starting point. - -Don't forget to make your handler executable before testing ! - -"Multiple" handlers -~~~~~~~~~~~~~~~~~~~ - -If you can program and want to write an ``execm`` handler, it should not -be too difficult to make sense of one of the existing handlers. - -The existing handlers differ in the amount of helper code which they are -using: - -- ``rclimg`` is written in Perl and handles the execm protocol all by - itself (showing how trivial it is). - -- All the Python handlers share at least the ``rclexecm.py`` module, - which handles the communication. Have a look at, for example, - ``rclzip`` for a handler which uses ``rclexecm.py`` directly. - -- Most Python handlers which process single-document files by executing - another command are further abstracted by using the ``rclexec1.py`` - module. See for example ``rclrtf.py`` for a simple one, or - ``rcldoc.py`` for a slightly more complicated one (possibly executing - several commands). - -- Handlers which extract text from an XML document by using an XSLT - style sheet are now executed inside ``recollindex``, with only the - style sheet stored in the ``filters/`` directory. These can use a - single style sheet (e.g. ``abiword.xsl``), or two sheets for the data - and metadata (e.g. ``opendoc-body.xsl`` and ``opendoc-meta.xsl``). - The ``mimeconf`` configuration file defines how the sheets are used, - have a look. Before the C++ import, the xsl-based handlers used a - common module ``rclgenxslt.py``, it is still around but unused. The - handler for OpenXML presentations is still the Python version because - the format did not fit with what the C++ code does. It would be a - good base for another similar issue. - -There is a sample trivial handler based on ``rclexecm.py``, with many -comments, not actually used by RCL. It would index a text file as one -document per line. Look for ``rcltxtlines.py`` in the ``src/filters`` -directory in the online RCL `Git -repository `__ (the sample not -in the distributed release at the moment). - -You can also have a look at the slightly more complex ``rclzip`` which -uses Zip file paths as identifiers (``ipath``). - -``execm`` handlers sometimes need to make a choice for the nature of the -``ipath`` elements that they use in communication with the indexer. Here -are a few guidelines: - -- Use ASCII or UTF-8 (if the identifier is an integer print it, for - example, like printf %d would do). - -- If at all possible, the data should make some kind of sense when - printed to a log file to help with debugging. - -- RCL uses a colon (``:``) as a separator to store a complex path - internally (for deeper embedding). Colons inside the ``ipath`` - elements output by a handler will be escaped, but would be a bad - choice as a handler-specific separator (mostly, again, for debugging - issues). - -In any case, the main goal is that it should be easy for the handler to -extract the target document, given the file name and the ``ipath`` -element. - -``execm`` handlers will also produce a document with a null ``ipath`` -element. Depending on the type of document, this may have some -associated data (e.g. the body of an email message), or none (typical -for an archive file). If it is empty, this document will be useful -anyway for some operations, as the parent of the actual data documents. - -Telling RCL about the handler -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -There are two elements that link a file to the handler which should -process it: the association of file to MIME type and the association of -a MIME type with a handler. - -The association of files to MIME types is mostly based on name suffixes. -The types are defined inside the ```mimemap`` -file <#RCL.INSTALL.CONFIG.MIMEMAP>`__. Example: - -:: - - - .doc = application/msword - - -If no suffix association is found for the file name, RCL will try to -execute a system command (typically ``file -i`` or ``xdg-mime``) to -determine a MIME type. - -The second element is the association of MIME types to handlers in the -```mimeconf`` file <#RCL.INSTALL.CONFIG.MIMECONF>`__. A sample will -probably be better than a long explanation: - -:: - - - [index] - application/msword = exec antiword -t -i 1 -m UTF-8;\ - mimetype = text/plain ; charset=utf-8 - - application/ogg = exec rclogg - - text/rtf = exec unrtf --nopict --html; charset=iso-8859-1; mimetype=text/html - - application/x-chm = execm rclchm - - -The fragment specifies that: - -- ``application/msword`` files are processed by executing the - ``antiword`` program, which outputs ``text/plain`` encoded in - ``utf-8``. - -- ``application/ogg`` files are processed by the ``rclogg`` script, - with default output type (``text/html``, with encoding specified in - the header, or ``utf-8`` by default). - -- ``text/rtf`` is processed by ``unrtf``, which outputs ``text/html``. - The ``iso-8859-1`` encoding is specified because it is not the - ``utf-8`` default, and not output by ``unrtf`` in the HTML header - section. - -- ``application/x-chm`` is processed by a persistant handler. This is - determined by the ``execm`` keyword. - -Input handler output -~~~~~~~~~~~~~~~~~~~~ - -Both the simple and persistent input handlers can return any MIME type -to Recoll, which will further process the data according to the MIME -configuration. - -Most input filters filters produce either ``text/plain`` or -``text/html`` data. There are exceptions, for example, filters which -process archive file (``zip``, ``tar``, etc.) will usually return the -documents as they are found, without processing them further. - -There is nothing to say about ``text/plain`` output, except that its -character encoding should be consistent with what is specified in the -``mimeconf`` file. - -For filters producing HTML, the output could be very minimal like the -following example: - -:: - - - - - - - Some text content - - - - -You should take care to escape some characters inside the text by -transforming them into appropriate entities. At the very minimum, -"``&``" should be transformed into "``&``", "``<``" should be -transformed into "``<``". This is not always properly done by -external helper programs which output HTML, and of course never by those -which output plain text. - -When encapsulating plain text in an HTML body, the display of a preview -may be improved by enclosing the text inside ``
`` tags.
-
-The character set needs to be specified in the header. It does not need
-to be UTF-8 (RCL will take care of translating it), but it must be
-accurate for good results.
-
-RCL will process ``meta`` tags inside the header as possible document
-fields candidates. Documents fields can be processed by the indexer in
-different ways, for searching or displaying inside query results. This
-is described in a `following section. <#RCL.PROGRAM.FIELDS>`__
-
-By default, the indexer will process the standard header fields if they
-are present: ``title``, ``meta/description``, and ``meta/keywords`` are
-both indexed and stored for query-time display.
-
-A predefined non-standard ``meta`` tag will also be processed by RCL
-without further configuration: if a ``date`` tag is present and has the
-right format, it will be used as the document date (for display and
-sorting), in preference to the file modification date. The date format
-should be as follows:
-
-::
-
-              
-              or
-              
-            
-
-Example:
-
-::
-
-              
-            
-
-Input handlers also have the possibility to "invent" field names. This
-should also be output as meta tags:
-
-::
-
-              
-            
-
-You can embed HTML markup inside the content of custom fields, for
-improving the display inside result lists. In this case, add a (wildly
-non-standard) ``markup`` attribute to tell RCL that the value is HTML
-and should not be escaped for display.
-
-::
-
-              
-            
-
-As written above, the processing of fields is described in a `further
-section <#RCL.PROGRAM.FIELDS>`__.
-
-Persistent filters can use another, probably simpler, method to produce
-metadata, by calling the ``setfield()`` helper method. This avoids the
-necessity to produce HTML, and any issue with HTML quoting. See, for
-example, ``rclaudio`` in RCL 1.23 and later for an example of handler
-which outputs ``text/plain`` and uses ``setfield()`` to produce
-metadata.
-
-Page numbers
-~~~~~~~~~~~~
-
-The indexer will interpret ``^L`` characters in the handler output as
-indicating page breaks, and will record them. At query time, this allows
-starting a viewer on the right page for a hit or a snippet. Currently,
-only the PDF, Postscript and DVI handlers generate page breaks.
-
-Field data processing
----------------------
-
-``Fields`` are named pieces of information in or about documents, like
-``title``, ``author``, ``abstract``.
-
-The field values for documents can appear in several ways during
-indexing: either output by input handlers as ``meta`` fields in the HTML
-header section, or extracted from file extended attributes, or added as
-attributes of the ``Doc`` object when using the API, or again
-synthetized internally by RCL.
-
-The RCL query language allows searching for text in a specific field.
-
-RCL defines a number of default fields. Additional ones can be output by
-handlers, and described in the ``fields`` configuration file.
-
-Fields can be:
-
--  ``indexed``, meaning that their terms are separately stored in
-   inverted lists (with a specific prefix), and that a field-specific
-   search is possible.
-
--  ``stored``, meaning that their value is recorded in the index data
-   record for the document, and can be returned and displayed with
-   search results.
-
-A field can be either or both indexed and stored. This and other aspects
-of fields handling is defined inside the ``fields`` configuration file.
-
-Some fields may also designated as supporting range queries, meaning
-that the results may be selected for an interval of its values. See the
-`configuration section <#RCL.INSTALL.CONFIG.FIELDS>`__ for more details.
-
-The sequence of events for field processing is as follows:
-
--  During indexing, ``recollindex`` scans all ``meta`` fields in HTML
-   documents (most document types are transformed into HTML at some
-   point). It compares the name for each element to the configuration
-   defining what should be done with fields (the ``fields`` file)
-
--  If the name for the ``meta`` element matches one for a field that
-   should be indexed, the contents are processed and the terms are
-   entered into the index with the prefix defined in the ``fields``
-   file.
-
--  If the name for the ``meta`` element matches one for a field that
-   should be stored, the content of the element is stored with the
-   document data record, from which it can be extracted and displayed at
-   query time.
-
--  At query time, if a field search is performed, the index prefix is
-   computed and the match is only performed against appropriately
-   prefixed terms in the index.
-
--  At query time, the field can be displayed inside the result list by
-   using the appropriate directive in the definition of the `result list
-   paragraph format <#RCL.SEARCH.GUI.CUSTOM.RESLIST>`__. All fields are
-   displayed on the fields screen of the preview window (which you can
-   reach through the right-click menu). This is independant of the fact
-   that the search which produced the results used the field or not.
-
-You can find more information in the `section about the ``fields``
-file <#RCL.INSTALL.CONFIG.FIELDS>`__, or in comments inside the file.
-
-You can also have a look at the `example in the FAQs
-area <&FAQS;HandleCustomField>`__, detailing how one could add a *page
-count* field to pdf documents for displaying inside result lists.
-
-Python API
-----------
-
-Introduction
-~~~~~~~~~~~~
-
-The RCL Python programming interface can be used both for searching and
-for creating/updating an index. Bindings exist for Python2 and Python3.
-
-The search interface is used in a number of active projects: the RCL
-Gnome Shell Search Provider, the RCL Web UI, and the upmpdcli UPnP Media
-Server, in addition to many small scripts.
-
-The index update section of the API may be used to create and update RCL
-indexes on specific configurations (separate from the ones created by
-``recollindex``). The resulting databases can be queried alone, or in
-conjunction with regular ones, through the GUI or any of the query
-interfaces.
-
-The search API is modeled along the Python database API specification.
-There were two major changes along RCL versions:
-
--  The basis for the RCL API changed from Python database API version
-   1.0 (RCL versions up to 1.18.1), to version 2.0 (RCL 1.18.2 and
-   later).
-
--  The ``recoll`` module became a package (with an internal ``recoll``
-   module) as of RCL version 1.19, in order to add more functions. For
-   existing code, this only changes the way the interface must be
-   imported.
-
-We will describe the new API and package structure here. A paragraph at
-the end of this section will explain a few differences and ways to write
-code compatible with both versions.
-
-The ``recoll`` package now contains two modules:
-
--  The ``recoll`` module contains functions and classes used to query
-   (or update) the index.
-
--  The ``rclextract`` module contains functions and classes used at
-   query time to access document data.
-
-There is a good chance that your system repository has packages for the
-Recoll Python API, sometimes in a package separate from the main one
-(maybe named something like python-recoll). Else refer to the `Building
-from source chapter <#RCL.INSTALL.BUILDING>`__.
-
-As an introduction, the following small sample will run a query and list
-the title and url for each of the results. It would work with RCL 1.19
-and later. The ``python/samples`` source directory contains several
-examples of Python programming with RCL, exercising the extension more
-completely, and especially its data extraction features.
-
-::
-
-            #!/usr/bin/env python
-
-            from recoll import recoll
-
-            db = recoll.connect()
-            query = db.query()
-            nres = query.execute("some query")
-            results = query.fetchmany(20)
-            for doc in results:
-                print("%s %s" % (doc.url, doc.title))
-            
-
-You can also take a look at the source for the `Recoll
-WebUI `__,
-the `upmpdcli local media
-server `__,
-or the `Gnome Shell Search
-Provider `__.
-
-Interface elements
-~~~~~~~~~~~~~~~~~~
-
-A few elements in the interface are specific and and need an
-explanation.
-
-ipath
-    This data value (set as a field in the Doc object) is stored, along
-    with the URL, but not indexed by RCL. Its contents are not
-    interpreted by the index layer, and its use is up to the
-    application. For example, the RCL file system indexer uses the
-    ``ipath`` to store the part of the document access path internal to
-    (possibly imbricated) container documents. ``ipath`` in this case is
-    a vector of access elements (e.g, the first part could be a path
-    inside a zip file to an archive member which happens to be an mbox
-    file, the second element would be the message sequential number
-    inside the mbox etc.). ``url`` and ``ipath`` are returned in every
-    search result and define the access to the original document.
-    ``ipath`` is empty for top-level document/files (e.g. a PDF document
-    which is a filesystem file). The RCL GUI knows about the structure
-    of the ``ipath`` values used by the filesystem indexer, and uses it
-    for such functions as opening the parent of a given document.
-
-udi
-    An ``udi`` (unique document identifier) identifies a document.
-    Because of limitations inside the index engine, it is restricted in
-    length (to 200 bytes), which is why a regular URI cannot be used.
-    The structure and contents of the ``udi`` is defined by the
-    application and opaque to the index engine. For example, the
-    internal file system indexer uses the complete document path (file
-    path + internal path), truncated to length, the suppressed part
-    being replaced by a hash value. The ``udi`` is not explicit in the
-    query interface (it is used "under the hood" by the ``rclextract``
-    module), but it is an explicit element of the update interface.
-
-parent\_udi
-    If this attribute is set on a document when entering it in the
-    index, it designates its physical container document. In a
-    multilevel hierarchy, this may not be the immediate parent.
-    ``parent_udi`` is optional, but its use by an indexer may simplify
-    index maintenance, as RCL will automatically delete all children
-    defined by ``parent_udi == udi`` when the document designated by
-    ``udi`` is destroyed. e.g. if a ``Zip`` archive contains entries
-    which are themselves containers, like ``mbox`` files, all the
-    subdocuments inside the ``Zip`` file (mbox, messages, message
-    attachments, etc.) would have the same ``parent_udi``, matching the
-    ``udi`` for the ``Zip`` file, and all would be destroyed when the
-    ``Zip`` file (identified by its ``udi``) is removed from the index.
-    The standard filesystem indexer uses ``parent_udi``.
-
-Stored and indexed fields
-    The ```fields`` file <#RCL.INSTALL.CONFIG.FIELDS>`__ inside the RCL
-    configuration defines which document fields are either ``indexed``
-    (searchable), ``stored`` (retrievable with search results), or both.
-    Apart from a few standard/internal fields, only the ``stored``
-    fields are retrievable through the Python search interface.
-
-Python search interface
-~~~~~~~~~~~~~~~~~~~~~~~
-
-The recoll module
-^^^^^^^^^^^^^^^^^
-
-The ``connect()`` function connects to one or several RCL index(es) and
-returns a ``Db`` object.
-
-This call initializes the recoll module, and it should always be
-performed before any other call or object creation.
-
--  ``confdir`` may specify a configuration directory. The usual defaults
-   apply.
-
--  ``extra_dbs`` is a list of additional indexes (Xapian directories).
-
--  ``writable`` decides if we can index new data through this
-   connection.
-
-A Db object is created by a ``connect()`` call and holds a connection to
-a Recoll index.
-
-Db.close()
-    Closes the connection. You can't do anything with the ``Db`` object
-    after this.
-
-Db.query(), Db.cursor()
-    These aliases return a blank ``Query`` object for this index.
-
-Db.setAbstractParams(maxchars, contextwords)
-    Set the parameters used to build snippets (sets of keywords in
-    context text fragments). ``maxchars`` defines the maximum total size
-    of the abstract. ``contextwords`` defines how many terms are shown
-    around the keyword.
-
-Db.termMatch(match\_type, expr, field='', maxlen=-1, casesens=False,
-diacsens=False, lang='english')
-    Expand an expression against the index term list. Performs the basic
-    function from the GUI term explorer tool. ``match_type`` can be
-    either of ``wildcard``, ``regexp`` or ``stem``. Returns a list of
-    terms expanded from the input expression.
-
-A ``Query`` object (equivalent to a cursor in the Python DB API) is
-created by a ``Db.query()`` call. It is used to execute index searches.
-
-Query.sortby(fieldname, ascending=True)
-    Sort results by fieldname, in ascending or descending order. Must be
-    called before executing the search.
-
-Query.execute(query\_string, stemming=1, stemlang="english",
-fetchtext=False)
-    Starts a search for query\_string, a RCL search language string. If
-    the index stores the document texts and ``fetchtext`` is True, store
-    the document extracted text in ``doc.text``.
-
-Query.executesd(SearchData, fetchtext=False)
-    Starts a search for the query defined by the SearchData object. If
-    the index stores the document texts and ``fetchtext`` is True, store
-    the document extracted text in ``doc.text``.
-
-Query.fetchmany(size=query.arraysize)
-    Fetches the next ``Doc`` objects in the current search results, and
-    returns them as an array of the required size, which is by default
-    the value of the ``arraysize`` data member.
-
-Query.fetchone()
-    Fetches the next ``Doc`` object from the current search results.
-    Generates a StopIteration exception if there are no results left.
-
-Query.close()
-    Closes the query. The object is unusable after the call.
-
-Query.scroll(value, mode='relative')
-    Adjusts the position in the current result set. ``mode`` can be
-    ``relative`` or ``absolute``.
-
-Query.getgroups()
-    Retrieves the expanded query terms as a list of pairs. Meaningful
-    only after executexx In each pair, the first entry is a list of user
-    terms (of size one for simple terms, or more for group and phrase
-    clauses), the second a list of query terms as derived from the user
-    terms and used in the Xapian Query.
-
-Query.getxquery()
-    Return the Xapian query description as a Unicode string. Meaningful
-    only after executexx.
-
-Query.highlight(text, ishtml = 0, methods = object)
-    Will insert ,  tags around the match
-    areas in the input text and return the modified text. ``ishtml`` can
-    be set to indicate that the input text is HTML and that HTML special
-    characters should not be escaped. ``methods`` if set should be an
-    object with methods startMatch(i) and endMatch() which will be
-    called for each match and should return a begin and end tag
-
-Query.makedocabstract(doc, methods = object))
-    Create a snippets abstract for ``doc`` (a ``Doc`` object) by
-    selecting text around the match terms. If methods is set, will also
-    perform highlighting. See the highlight method.
-
-Query.\_\_iter\_\_() and Query.next()
-    So that things like ``for doc in query:`` will work.
-
-Query.arraysize
-    Default number of records processed by fetchmany (r/w).
-
-Query.rowcount
-    Number of records returned by the last execute.
-
-Query.rownumber
-    Next index to be fetched from results. Normally increments after
-    each fetchone() call, but can be set/reset before the call to effect
-    seeking (equivalent to using ``scroll()``). Starts at 0.
-
-A ``Doc`` object contains index data for a given document. The data is
-extracted from the index when searching, or set by the indexer program
-when updating. The Doc object has many attributes to be read or set by
-its user. It mostly matches the Rcl::Doc C++ object. Some of the
-attributes are predefined, but, especially when indexing, others can be
-set, the name of which will be processed as field names by the indexing
-configuration. Inputs can be specified as Unicode or strings. Outputs
-are Unicode objects. All dates are specified as Unix timestamps, printed
-as strings. Please refer to the ``rcldb/rcldoc.cpp`` C++ file for a full
-description of the predefined attributes. Here follows a short list.
-
--  ``url`` the document URL but see also ``getbinurl()``
-
--  ``ipath`` the document ``ipath`` for embedded documents.
-
--  ``fbytes, dbytes`` the document file and text sizes.
-
--  ``fmtime, dmtime`` the document file and document times.
-
--  ``xdocid`` the document Xapian document ID. This is useful if you
-   want to access the document through a direct Xapian operation.
-
--  ``mtype`` the document MIME type.
-
--  Fields stored by default: ``author``, ``filename``, ``keywords``,
-   ``recipient``
-
-At query time, only the fields that are defined as ``stored`` either by
-default or in the ``fields`` configuration file will be meaningful in
-the ``Doc`` object. The document processed text may be present or not,
-depending if the index stores the text at all, and if it does, on the
-``fetchtext`` query execute option. See also the ``rclextract`` module
-for accessing document contents.
-
-get(key), [] operator
-    Retrieve the named document attribute. You can also use
-    ``getattr(doc, key)`` or ``doc.key``.
-
-doc.key = value
-    Set the the named document attribute. You can also use
-    ``setattr(doc, key, value)``.
-
-getbinurl()
-    Retrieve the URL in byte array format (no transcoding), for use as
-    parameter to a system call.
-
-setbinurl(url)
-    Set the URL in byte array format (no transcoding).
-
-items()
-    Return a dictionary of doc object keys/values
-
-keys()
-    list of doc object keys (attribute names).
-
-A ``SearchData`` object allows building a query by combining clauses,
-for execution by ``Query.executesd()``. It can be used in replacement of
-the query language approach. The interface is going to change a little,
-so no detailed doc for now...
-
-addclause(type='and'\|'or'\|'excl'\|'phrase'\|'near'\|'sub',
-qstring=string, slack=0, field='', stemming=1, subSearch=SearchData)
-
-The rclextract module
-^^^^^^^^^^^^^^^^^^^^^
-
-Prior to RCL 1.25, index queries could not provide document content
-because it was never stored. RCL 1.25 and later usually store the
-document text, which can be optionally retrieved when running a query
-(see ``query.execute()`` above - the result is always plain text).
-
-The ``rclextract`` module can give access to the original document and
-to the document text content (if not stored by the index, or to access
-an HTML version of the text). Acessing the original document is
-particularly useful if it is embedded (e.g. an email attachment).
-
-You need to import the ``recoll`` module before the ``rclextract``
-module.
-
-Extractor(doc)
-    An ``Extractor`` object is built from a ``Doc`` object, output from
-    a query.
-
-Extractor.textextract(ipath)
-    Extract document defined by ipath and return a ``Doc`` object. The
-    ``doc.text`` field has the document text converted to either
-    text/plain or text/html according to ``doc.mimetype``. The typical
-    use would be as follows:
-
-    ::
-
-        from recoll import recoll, rclextract
-
-        qdoc = query.fetchone()
-        extractor = recoll.Extractor(qdoc)
-        doc = extractor.textextract(qdoc.ipath)
-        # use doc.text, e.g. for previewing
-
-    Passing ``qdoc.ipath`` to ``textextract()`` is redundant, but
-    reflects the fact that the ``Extractor`` object actually has the
-    capability to access the other entries in a compound document.
-
-Extractor.idoctofile(ipath, targetmtype, outfile='')
-    Extracts document into an output file, which can be given explicitly
-    or will be created as a temporary file to be deleted by the caller.
-    Typical use:
-
-    ::
-
-        from recoll import recoll, rclextract
-
-        qdoc = query.fetchone()
-        extractor = recoll.Extractor(qdoc)
-        filename = extractor.idoctofile(qdoc.ipath, qdoc.mimetype)
-
-    In all cases the output is a copy, even if the requested document is
-    a regular system file, which may be wasteful in some cases. If you
-    want to avoid this, you can test for a simple file document as
-    follows:
-
-    ::
-
-        not doc.ipath and (not "rclbes" in doc.keys() or doc["rclbes"] == "FS")
-
-Search API usage example
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-The following sample would query the index with a user language string.
-See the ``python/samples`` directory inside the RCL source for other
-examples. The ``recollgui`` subdirectory has a very embryonic GUI which
-demonstrates the highlighting and data extraction functions.
-
-::
-
-    #!/usr/bin/env python
-
-    from recoll import recoll
-
-    db = recoll.connect()
-    db.setAbstractParams(maxchars=80, contextwords=4)
-
-    query = db.query()
-    nres = query.execute("some user question")
-    print "Result count: ", nres
-    if nres > 5:
-        nres = 5
-    for i in range(nres):
-        doc = query.fetchone()
-        print "Result #%d" % (query.rownumber,)
-        for k in ("title", "size"):
-            print k, ":", getattr(doc, k).encode('utf-8')
-        abs = db.makeDocAbstract(doc, query).encode('utf-8')
-        print abs
-        print
-
-Creating Python external indexers
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The update API can be used to create an index from data which is not
-accessible to the regular RCL indexer, or structured to present
-difficulties to the RCL input handlers.
-
-An indexer created using this API will be have equivalent work to do as
-the the Recoll file system indexer: look for modified documents, extract
-their text, call the API for indexing it, take care of purging the index
-out of data from documents which do not exist in the document store any
-more.
-
-The data for such an external indexer should be stored in an index
-separate from any used by the RCL internal file system indexer. The
-reason is that the main document indexer purge pass (removal of deleted
-documents) would also remove all the documents belonging to the external
-indexer, as they were not seen during the filesystem walk. The main
-indexer documents would also probably be a problem for the external
-indexer own purge operation.
-
-While there would be ways to enable multiple foreign indexers to
-cooperate on a single index, it is just simpler to use separate ones,
-and use the multiple index access capabilities of the query interface,
-if needed.
-
-There are two parts in the update interface:
-
--  Methods inside the ``recoll`` module allow inserting data into the
-   index, to make it accessible by the normal query interface.
-
--  An interface based on scripts execution is defined to allow either
-   the GUI or the ``rclextract`` module to access original document data
-   for previewing or editing.
-
-Python update interface
-^^^^^^^^^^^^^^^^^^^^^^^
-
-The update methods are part of the ``recoll`` module described above.
-The connect() method is used with a ``writable=true`` parameter to
-obtain a writable ``Db`` object. The following ``Db`` object methods are
-then available.
-
-addOrUpdate(udi, doc, parent\_udi=None)
-    Add or update index data for a given document The ``udi`` string
-    must define a unique id for the document. It is an opaque interface
-    element and not interpreted inside Recoll. ``doc`` is a ``Doc``
-    object, created from the data to be indexed (the main text should be
-    in ``doc.text``). If ``parent_udi`` is set, this is a unique
-    identifier for the top-level container (e.g. for the filesystem
-    indexer, this would be the one which is an actual file).
-
-delete(udi)
-    Purge index from all data for ``udi``, and all documents (if any)
-    which have a matrching ``parent_udi``.
-
-needUpdate(udi, sig)
-    Test if the index needs to be updated for the document identified by
-    ``udi``. If this call is to be used, the ``doc.sig`` field should
-    contain a signature value when calling ``addOrUpdate()``. The
-    ``needUpdate()`` call then compares its parameter value with the
-    stored ``sig`` for ``udi``. ``sig`` is an opaque value, compared as
-    a string.
-
-    The filesystem indexer uses a concatenation of the decimal string
-    values for file size and update time, but a hash of the contents
-    could also be used.
-
-    As a side effect, if the return value is false (the index is up to
-    date), the call will set the existence flag for the document (and
-    any subdocument defined by its ``parent_udi``), so that a later
-    ``purge()`` call will preserve them).
-
-    The use of ``needUpdate()`` and ``purge()`` is optional, and the
-    indexer may use another method for checking the need to reindex or
-    to delete stale entries.
-
-purge()
-    Delete all documents that were not touched during the just finished
-    indexing pass (since open-for-write). These are the documents for
-    the needUpdate() call was not performed, indicating that they no
-    longer exist in the primary storage system.
-
-Query data access for external indexers (1.23)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-RCL has internal methods to access document data for its internal
-(filesystem) indexer. An external indexer needs to provide data access
-methods if it needs integration with the GUI (e.g. preview function), or
-support for the ``rclextract`` module.
-
-The index data and the access method are linked by the ``rclbes``
-(recoll backend storage) ``Doc`` field. You should set this to a short
-string value identifying your indexer (e.g. the filesystem indexer uses
-either "FS" or an empty value, the Web history indexer uses "BGL").
-
-The link is actually performed inside a ``backends`` configuration file
-(stored in the configuration directory). This defines commands to
-execute to access data from the specified indexer. Example, for the mbox
-indexing sample found in the Recoll source (which sets
-``rclbes="MBOX"``):
-
-::
-
-    [MBOX]
-              fetch = /path/to/recoll/src/python/samples/rclmbox.py fetch
-              makesig = path/to/recoll/src/python/samples/rclmbox.py makesig
-              
-
-``fetch`` and ``makesig`` define two commands to execute to respectively
-retrieve the document text and compute the document signature (the
-example implementation uses the same script with different first
-parameters to perform both operations).
-
-The scripts are called with three additional arguments: ``udi``,
-``url``, ``ipath``, stored with the document when it was indexed, and
-may use any or all to perform the requested operation. The caller
-expects the result data on ``stdout``.
-
-External indexer samples
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-The Recoll source tree has two samples of external indexers in the
-``src/python/samples`` directory. The more interesting one is
-``rclmbox.py`` which indexes a directory containing ``mbox`` folder
-files. It exercises most features in the update interface, and has a
-data access interface.
-
-See the comments inside the file for more information.
-
-Package compatibility with the previous version
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following code fragments can be used to ensure that code can run
-with both the old and the new API (as long as it does not use the new
-abilities of the new API of course).
-
-Adapting to the new package structure:
-
-::
-
-              
-                       try:
-                       from recoll import recoll
-                       from recoll import rclextract
-                       hasextract = True
-                       except:
-                       import recoll
-                       hasextract = False
-              
-            
-
-Adapting to the change of nature of the ``next`` ``Query`` member. The
-same test can be used to choose to use the ``scroll()`` method (new) or
-set the ``next`` value (old).
-
-::
-
-              
-                       rownum = query.next if type(query.next) == int else \
-                       query.rownumber
-              
-            
-
-Installation and configuration
-==============================
-
-Installing a binary copy
-------------------------
-
-RCL binary copies are always distributed as regular packages for your
-system. They can be obtained either through the system's normal software
-distribution framework (e.g. Debian/Ubuntu apt, FreeBSD ports, etc.), or
-from some type of "backports" repository providing versions newer than
-the standard ones, or found on the RCL WEB site in some cases. The most
-up-to-date information about Recoll packages can usually be found on the
-`Recoll WEB site downloads page `__
-
-There used to exist another form of binary install, as pre-compiled
-source trees, but these are just less convenient than the packages and
-don't exist any more.
-
-The package management tools will usually automatically deal with hard
-dependancies for packages obtained from a proper package repository. You
-will have to deal with them by hand for downloaded packages (for
-example, when ``dpkg`` complains about missing dependancies).
-
-In all cases, you will have to check or install `supporting
-applications <#RCL.INSTALL.EXTERNAL>`__ for the file types that you want
-to index beyond those that are natively processed by RCL (text, HTML,
-email files, and a few others).
-
-You should also maybe have a look at the `configuration
-section <#RCL.INSTALL.CONFIG>`__ (but this may not be necessary for a
-quick test with default parameters). Most parameters can be more
-conveniently set from the GUI interface.
-
-Supporting packages
--------------------
-
-    **Note**
-
-    The WIN installation of RCL is self-contained, and only needs Python
-    2.7 to be externally installed. WIN users can skip this section.
-
-RCL uses external applications to index some file types. You need to
-install them for the file types that you wish to have indexed (these are
-run-time optional dependencies. None is needed for building or running
-RCL except for indexing their specific file type).
-
-After an indexing pass, the commands that were found missing can be
-displayed from the ``recoll`` File menu. The list is stored in the
-``missing`` text file inside the configuration directory.
-
-A list of common file types which need external commands follows. Many
-of the handlers need the ``iconv`` command, which is not always listed
-as a dependancy.
-
-Please note that, due to the relatively dynamic nature of this
-information, the most up to date version is now kept on RCLAPPS along
-with links to the home pages or best source/patches pages, and misc
-tips. The list below is not updated often and may be quite stale.
-
-For many Linux distributions, most of the commands listed can be
-installed from the package repositories. However, the packages are
-sometimes outdated, or not the best version for RCL, so you should take
-a look at RCLAPPS if a file type is important to you.
-
-As of RCL release 1.14, a number of XML-based formats that were handled
-by ad hoc handler code now use the ``xsltproc`` command, which usually
-comes with libxslt. These are: abiword, fb2 (ebooks), kword, openoffice,
-svg.
-
-Now for the list:
-
--  Openoffice files need ``unzip`` and ``xsltproc``.
-
--  PDF files need ``pdftotext`` which is part of Poppler (usually comes
-   with the ``poppler-utils`` package). Avoid the original one from
-   Xpdf.
-
--  Postscript files need ``pstotext``. The original version has an issue
-   with shell character in file names, which is corrected in recent
-   packages. See RCLAPPS for more detail.
-
--  MS Word needs ``antiword``. It is also useful to have ``wvWare``
-   installed as it may be be used as a fallback for some files which
-   ``antiword`` does not handle.
-
--  MS Excel and PowerPoint are processed by internal ``Python``
-   handlers.
-
--  MS Open XML (docx) needs ``
-           xsltproc``.
-
--  Wordperfect files need ``wpd2html`` from the libwpd (or libwpd-tools
-   on Ubuntu) package.
-
--  RTF files need ``unrtf``, which, in its older versions, has much
-   trouble with non-western character sets. Many Linux distributions
-   carry outdated ``unrtf`` versions. Check RCLAPPS for details.
-
--  TeX files need ``untex`` or ``detex``. Check RCLAPPS for sources if
-   it's not packaged for your distribution.
-
--  dvi files need ``dvips``.
-
--  djvu files need ``djvutxt`` and ``djvused`` from the DjVuLibre
-   package.
-
--  Audio files: RCL releases 1.14 and later use a single Python handler
-   based on mutagen for all audio file types.
-
--  Pictures: RCL uses the Exiftool Perl package to extract tag
-   information. Most image file formats are supported. Note that there
-   may not be much interest in indexing the technical tags (image size,
-   aperture, etc.). This is only of interest if you store personal tags
-   or textual descriptions inside the image files.
-
--  chm: files in Microsoft help format need Python and the pychm module
-   (which needs chmlib).
-
--  ICS: up to RCL 1.13, iCalendar files need Python and the icalendar
-   module. icalendar is not needed for newer versions, which use
-   internal code.
-
--  Zip archives need Python (and the standard zipfile module).
-
--  Rar archives need Python, the rarfile Python module and the ``unrar``
-   utility.
-
--  Midi karaoke files need Python and the `Midi
-   module `__
-
--  Konqueror webarchive format with Python (uses the Tarfile module).
-
--  Mimehtml web archive format (support based on the email handler,
-   which introduces some mild weirdness, but still usable).
-
-Text, HTML, email folders, and Scribus files are processed internally.
-Lyx is used to index Lyx files. Many handlers need ``iconv`` and the
-standard ``sed`` and ``awk``.
-
-Building from source
---------------------
-
-Prerequisites
-~~~~~~~~~~~~~
-
-The following prerequisites are described in broad terms and not as
-specific package names (which will depend on the exact platform). The
-dependancies should be available as packages on most common Unix
-derivatives, and it should be quite uncommon that you would have to
-build one of them.
-
-The shopping list:
-
--  The ``autoconf``, ``automake`` and ``libtool`` triad. Only
-   ``autoconf`` is needed for RCL 1.21 and earlier.
-
--  C++ compiler. Recent versions require C++11 compatibility (1.23 and
-   later).
-
--  ``bison`` command (for RCL 1.21 and later).
-
--  ``xsltproc`` command. For building the documentation (for RCL 1.21
-   and later). This sometimes comes with the libxslt package. And also
-   the Docbook XML and style sheet files.
-
--  Development files for `Xapian core `__.
-
-       **Important**
-
-       If you are building Xapian for an older CPU (before Pentium 4 or
-       Athlon 64), you need to add the ``--disable-sse`` flag to the
-       configure command. Else all Xapian application will crash with an
-       ``illegal instruction`` error.
-
--  Development files for `Qt 4 or Qt
-   5 `__. RCL 1.15.9 was the last
-   version to support Qt 3. If you do not want to install or build the
-   Qt Webkit module, RCL has a configuration option to disable its use
-   (see further in the configuration section).
-
--  Development files for X11 and zlib.
-
--  Development files for Python (or use ``--disable-python-module``).
-
--  You may also need
-   `libiconv `__. On Linux
-   systems, the iconv interface is part of libc and you should not need
-   to do anything special.
-
-Check the `RCL download page `__
-for up to date version information.
-
-Building
-~~~~~~~~
-
-RCL has been built on Linux, FreeBSD, Mac OS X, and Solaris, most
-versions after 2005 should be ok, maybe some older ones too (Solaris 8
-is ok). If you build on another system, and need to modify things, `I
-would very much welcome patches `__.
-
-**Configure options:.**
-
--  ``--without-aspell`` will disable the code for phonetic matching of
-   search terms.
-
--  ``--with-fam`` or ``--with-inotify`` will enable the code for real
-   time indexing. Inotify support is enabled by default on recent Linux
-   systems.
-
--  ``--with-qzeitgeist`` will enable sending Zeitgeist events about the
-   visited search results, and needs the qzeitgeist package.
-
--  ``--disable-webkit`` is available from version 1.17 to implement the
-   result list with a Qt QTextBrowser instead of a WebKit widget if you
-   do not or can't depend on the latter.
-
--  ``--disable-idxthreads`` is available from version 1.19 to suppress
-   multithreading inside the indexing process. You can also use the
-   run-time configuration to restrict ``recollindex`` to using a single
-   thread, but the compile-time option may disable a few more unused
-   locks. This only applies to the use of multithreading for the core
-   index processing (data input). The RCL monitor mode always uses at
-   least two threads of execution.
-
--  ``--disable-python-module`` will avoid building the Python module.
-
--  ``--disable-xattr`` will prevent fetching data from file extended
-   attributes. Beyond a few standard attributes, fetching extended
-   attributes data can only be useful is some application stores data in
-   there, and also needs some simple configuration (see comments in the
-   ``fields`` configuration file).
-
--  ``--enable-camelcase`` will enable splitting camelCase words. This is
-   not enabled by default as it has the unfortunate side-effect of
-   making some phrase searches quite confusing: ie, ``"MySQL manual"``
-   would be matched by ``"MySQL manual"`` and ``"my sql manual"`` but
-   not ``"mysql manual"`` (only inside phrase searches).
-
--  ``--with-file-command`` Specify the version of the 'file' command to
-   use (ie: --with-file-command=/usr/local/bin/file). Can be useful to
-   enable the gnu version on systems where the native one is bad.
-
--  ``--disable-qtgui`` Disable the Qt interface. Will allow building the
-   indexer and the command line search program in absence of a Qt
-   environment.
-
--  ``--disable-x11mon`` Disable X11 connection monitoring inside
-   recollindex. Together with --disable-qtgui, this allows building
-   recoll without Qt and X11.
-
--  ``--disable-userdoc`` will avoid building the user manual. This
-   avoids having to install the Docbook XML/XSL files and the TeX
-   toolchain used for translating the manual to PDF.
-
--  ``--disable-pic`` (RCL versions up to 1.21 only) will compile RCL
-   with position-dependant code. This is incompatible with building the
-   KIO or the Python or PHP extensions, but might yield very marginally
-   faster code.
-
--  Of course the usual autoconf ``configure`` options, like ``--prefix``
-   apply.
-
-Normal procedure (for source extracted from a tar distribution):
-
-::
-
-              cd recoll-xxx
-              ./configure
-              make
-              (practices usual hardship-repelling invocations)
-            
-
-When building from source cloned from the git repository, you also need
-to install autoconf, automake, and libtool and you must execute
-``sh autogen.sh`` in the top source directory before running
-``configure``.
-
-Installing
-~~~~~~~~~~
-
-Use ``make install`` in the root of the source tree. This will copy the
-commands to ``prefix/bin`` and the sample configuration files, scripts
-and other shared data to ``prefix/share/recoll``.
-
-Python API package
-~~~~~~~~~~~~~~~~~~
-
-The Python interface can be found in the source tree, under the
-``python/recoll`` directory.
-
-As of RCL 1.19, the module can be compiled for Python3.
-
-The normal RCL build procedure (see above) installs the API package for
-the default system version (python) along with the main code. The
-package for other Python versions (e.g. python3 if the system default is
-python2) must be explicitely built and installed.
-
-The ``python/recoll/`` directory contains the usual ``setup.py``. After
-configuring and building the main RCL code, you can use the script to
-build and install the Python module:
-
-::
-
-              cd recoll-xxx/python/recoll
-              pythonX setup.py build
-              sudo pythonX setup.py install
-            
-
-Building on Solaris
-~~~~~~~~~~~~~~~~~~~
-
-We did not test building the GUI on Solaris for recent versions. You
-will need at least Qt 4.4. There are some hints on `an old web site
-page `__, they may still be
-valid.
-
-Someone did test the 1.19 indexer and Python module build, they do work,
-with a few minor glitches. Be sure to use GNU ``make`` and ``install``.
-
-Configuration overview
-----------------------
-
-Most of the parameters specific to the ``recoll`` GUI are set through
-the Preferences menu and stored in the standard Qt place
-(``$HOME/.config/Recoll.org/recoll.conf``). You probably do not want to
-edit this by hand.
-
-RCL indexing options are set inside text configuration files located in
-a configuration directory. There can be several such directories, each
-of which defines the parameters for one index.
-
-The configuration files can be edited by hand or through the Index
-configuration dialog (Preferences menu). The GUI tool will try to
-respect your formatting and comments as much as possible, so it is quite
-possible to use both approaches on the same configuration.
-
-The most accurate documentation for the configuration parameters is
-given by comments inside the default files, and we will just give a
-general overview here.
-
-For each index, there are at least two sets of configuration files.
-System-wide configuration files are kept in a directory named like
-``/usr/share/recoll/examples``, and define default values, shared by all
-indexes. For each index, a parallel set of files defines the customized
-parameters.
-
-The default location of the customized configuration is the ``.recoll``
-directory in your home. Most people will only use this directory.
-
-This location can be changed, or others can be added with the
-RECOLL\_CONFDIR environment variable or the ``-c`` option parameter to
-``recoll`` and ``recollindex``.
-
-In addition (as of RCL version 1.19.7), it is possible to specify two
-additional configuration directories which will be stacked before and
-after the user configuration directory. These are defined by the
-RECOLL\_CONFTOP and RECOLL\_CONFMID environment variables. Values from
-configuration files inside the top directory will override user ones,
-values from configuration files inside the middle directory will
-override system ones and be overriden by user ones. These two variables
-may be of use to applications which augment RCL functionality, and need
-to add configuration data without disturbing the user's files. Please
-note that the two, currently single, values will probably be interpreted
-as colon-separated lists in the future: do not use colon characters
-inside the directory paths.
-
-If the ``.recoll`` directory does not exist when ``recoll`` or
-``recollindex`` are started, it will be created with a set of empty
-configuration files. ``recoll`` will give you a chance to edit the
-configuration file before starting indexing. ``recollindex`` will
-proceed immediately. To avoid mistakes, the automatic directory creation
-will only occur for the default location, not if ``-c`` or
-RECOLL\_CONFDIR were used (in the latter cases, you will have to create
-the directory).
-
-All configuration files share the same format. For example, a short
-extract of the main configuration file might look as follows:
-
-::
-
-            # Space-separated list of files and directories to index.
-            topdirs =  ~/docs /usr/share/doc
-
-            [~/somedirectory-with-utf8-txt-files]
-            defaultcharset = utf-8
-          
-
-There are three kinds of lines:
-
--  Comment (starts with *#*) or empty.
-
--  Parameter affectation (*name = value*).
-
--  Section definition ([*somedirname*]).
-
-Long lines can be broken by ending each incomplete part with a backslash
-(``\``).
-
-Depending on the type of configuration file, section definitions either
-separate groups of parameters or allow redefining some parameters for a
-directory sub-tree. They stay in effect until another section
-definition, or the end of file, is encountered. Some of the parameters
-used for indexing are looked up hierarchically from the current
-directory location upwards. Not all parameters can be meaningfully
-redefined, this is specified for each in the next section.
-
-    **Important**
-
-    Global parameters *must not* be defined in a directory subsection,
-    else they will not be found at all by the RCL code, which looks for
-    them at the top level (e.g. ``skippedPaths``).
-
-When found at the beginning of a file path, the tilde character (~) is
-expanded to the name of the user's home directory, as a shell would do.
-
-Some parameters are lists of strings. White space is used for
-separation. List elements with embedded spaces can be quoted using
-double-quotes. Double quotes inside these elements can be escaped with a
-backslash.
-
-No value inside a configuration file can contain a newline character.
-Long lines can be continued by escaping the physical newline with
-backslash, even inside quoted strings.
-
-::
-
-            astringlist =  "some string \
-            with spaces"
-            thesame = "some string with spaces"        
-          
-
-Parameters which are not part of string lists can't be quoted, and
-leading and trailing space characters are stripped before the value is
-used.
-
-**Encoding issues.**
-
-Most of the configuration parameters are plain ASCII. Two particular
-sets of values may cause encoding issues:
-
--  File path parameters may contain non-ascii characters and should use
-   the exact same byte values as found in the file system directory.
-   Usually, this means that the configuration file should use the system
-   default locale encoding.
-
--  The unac\_except\_trans parameter should be encoded in UTF-8. If your
-   system locale is not UTF-8, and you need to also specify non-ascii
-   file paths, this poses a difficulty because common text editors
-   cannot handle multiple encodings in a single file. In this relatively
-   unlikely case, you can edit the configuration file as two separate
-   text files with appropriate encodings, and concatenate them to create
-   the complete configuration.
-
-Environment variables
-~~~~~~~~~~~~~~~~~~~~~
-
-``RECOLL_CONFDIR``
-    Defines the main configuration directory.
-
-``RECOLL_TMPDIR, TMPDIR``
-    Locations for temporary files, in this order of priority. The
-    default if none of these is set is to use ``/tmp``. Big temporary
-    files may be created during indexing, mostly for decompressing, and
-    also for processing, e.g. email attachments.
-
-``RECOLL_CONFTOP, RECOLL_CONFMID``
-    Allow adding configuration directories with priorities below and
-    above the user directory (see above the Configuration overview
-    section for details).
-
-``RECOLL_EXTRA_DBS, RECOLL_ACTIVE_EXTRA_DBS``
-    Help for setting up external indexes. See `this
-    paragraph <#RCL.SEARCH.GUI.MULTIDB>`__ for explanations.
-
-``RECOLL_DATADIR``
-    Defines replacement for the default location of Recoll data files,
-    normally found in, e.g., ``/usr/share/recoll``).
-
-``RECOLL_FILTERSDIR``
-    Defines replacement for the default location of Recoll filters,
-    normally found in, e.g., ``/usr/share/recoll/filters``).
-
-``ASPELL_PROG``
-    ``aspell`` program to use for creating the spelling dictionary. The
-    result has to be compatible with the ``libaspell`` which RCL is
-    using.
-
-``VARNAME``
-    Blabla
-
-Recoll main configuration file, recoll.conf
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Parameters affecting what documents we index
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-``topdirs``
-    Space-separated list of files or directories to recursively index.
-    Default to ~ (indexes $HOME). You can use symbolic links in the
-    list, they will be followed, independantly of the value of the
-    followLinks variable.
-
-``monitordirs``
-    Space-separated list of files or directories to monitor for updates.
-    When running the real-time indexer, this allows monitoring only a
-    subset of the whole indexed area. The elements must be included in
-    the tree defined by the 'topdirs' members.
-
-``skippedNames``
-    Files and directories which should be ignored. White space separated
-    list of wildcard patterns (simple ones, not paths, must contain no /
-    ), which will be tested against file and directory names. The list
-    in the default configuration does not exclude hidden directories
-    (names beginning with a dot), which means that it may index quite a
-    few things that you do not want. On the other hand, email user
-    agents like Thunderbird usually store messages in hidden
-    directories, and you probably want this indexed. One possible
-    solution is to have ".\*" in "skippedNames", and add things like
-    "~/.thunderbird" "~/.evolution" to "topdirs". Not even the file
-    names are indexed for patterns in this list, see the
-    "noContentSuffixes" variable for an alternative approach which
-    indexes the file names. Can be redefined for any subtree.
-
-``skippedNames-``
-    List of name endings to remove from the default skippedNames list.
-
-``skippedNames+``
-    List of name endings to add to the default skippedNames list.
-
-``noContentSuffixes``
-    List of name endings (not necessarily dot-separated suffixes) for
-    which we don't try MIME type identification, and don't uncompress or
-    index content. Only the names will be indexed. This complements the
-    now obsoleted recoll\_noindex list from the mimemap file, which will
-    go away in a future release (the move from mimemap to recoll.conf
-    allows editing the list through the GUI). This is different from
-    skippedNames because these are name ending matches only (not
-    wildcard patterns), and the file name itself gets indexed normally.
-    This can be redefined for subdirectories.
-
-``noContentSuffixes-``
-    List of name endings to remove from the default noContentSuffixes
-    list.
-
-``noContentSuffixes+``
-    List of name endings to add to the default noContentSuffixes list.
-
-``skippedPaths``
-    Absolute paths we should not go into. Space-separated list of
-    wildcard expressions for absolute filesystem paths. Must be defined
-    at the top level of the configuration file, not in a subsection. Can
-    contain files and directories. The database and configuration
-    directories will automatically be added. The expressions are matched
-    using 'fnmatch(3)' with the FNM\_PATHNAME flag set by default. This
-    means that '/' characters must be matched explicitely. You can set
-    'skippedPathsFnmPathname' to 0 to disable the use of FNM\_PATHNAME
-    (meaning that '/\*/dir3' will match '/dir1/dir2/dir3'). The default
-    value contains the usual mount point for removable media to remind
-    you that it is a bad idea to have Recoll work on these (esp. with
-    the monitor: media gets indexed on mount, all data gets erased on
-    unmount). Explicitely adding '/media/xxx' to the 'topdirs' variable
-    will override this.
-
-``skippedPathsFnmPathname``
-    Set to 0 to override use of FNM\_PATHNAME for matching skipped
-    paths.
-
-``nowalkfn``
-    File name which will cause its parent directory to be skipped. Any
-    directory containing a file with this name will be skipped as if it
-    was part of the skippedPaths list. Ex: .recoll-noindex
-
-``daemSkippedPaths``
-    skippedPaths equivalent specific to real time indexing. This enables
-    having parts of the tree which are initially indexed but not
-    monitored. If daemSkippedPaths is not set, the daemon uses
-    skippedPaths.
-
-``zipUseSkippedNames``
-    Use skippedNames inside Zip archives. Fetched directly by the rclzip
-    handler. Skip the patterns defined by skippedNames inside Zip
-    archives. Can be redefined for subdirectories. See
-    https://www.lesbonscomptes.com/recoll/faqsandhowtos/FilteringOutZipArchiveMembers.html
-
-``zipSkippedNames``
-    Space-separated list of wildcard expressions for names that should
-    be ignored inside zip archives. This is used directly by the zip
-    handler. If zipUseSkippedNames is not set, zipSkippedNames defines
-    the patterns to be skipped inside archives. If zipUseSkippedNames is
-    set, the two lists are concatenated and used. Can be redefined for
-    subdirectories. See
-    https://www.lesbonscomptes.com/recoll/faqsandhowtos/FilteringOutZipArchiveMembers.html
-
-``followLinks``
-    Follow symbolic links during indexing. The default is to ignore
-    symbolic links to avoid multiple indexing of linked files. No effort
-    is made to avoid duplication when this option is set to true. This
-    option can be set individually for each of the 'topdirs' members by
-    using sections. It can not be changed below the 'topdirs' level.
-    Links in the 'topdirs' list itself are always followed.
-
-``indexedmimetypes``
-    Restrictive list of indexed mime types. Normally not set (in which
-    case all supported types are indexed). If it is set, only the types
-    from the list will have their contents indexed. The names will be
-    indexed anyway if indexallfilenames is set (default). MIME type
-    names should be taken from the mimemap file (the values may be
-    different from xdg-mime or file -i output in some cases). Can be
-    redefined for subtrees.
-
-``excludedmimetypes``
-    List of excluded MIME types. Lets you exclude some types from
-    indexing. MIME type names should be taken from the mimemap file (the
-    values may be different from xdg-mime or file -i output in some
-    cases) Can be redefined for subtrees.
-
-``nomd5types``
-    Don't compute md5 for these types. md5 checksums are used only for
-    deduplicating results, and can be very expensive to compute on
-    multimedia or other big files. This list lets you turn off md5
-    computation for selected types. It is global (no redefinition for
-    subtrees). At the moment, it only has an effect for external
-    handlers (exec and execm). The file types can be specified by
-    listing either MIME types (e.g. audio/mpeg) or handler names (e.g.
-    rclaudio).
-
-``compressedfilemaxkbs``
-    Size limit for compressed files. We need to decompress these in a
-    temporary directory for identification, which can be wasteful in
-    some cases. Limit the waste. Negative means no limit. 0 results in
-    no processing of any compressed file. Default 50 MB.
-
-``textfilemaxmbs``
-    Size limit for text files. Mostly for skipping monster logs. Default
-    20 MB.
-
-``indexallfilenames``
-    Index the file names of unprocessed files Index the names of files
-    the contents of which we don't index because of an excluded or
-    unsupported MIME type.
-
-``usesystemfilecommand``
-    Use a system command for file MIME type guessing as a final step in
-    file type identification This is generally useful, but will usually
-    cause the indexing of many bogus 'text' files. See
-    'systemfilecommand' for the command used.
-
-``systemfilecommand``
-    Command used to guess MIME types if the internal methods fails This
-    should be a "file -i" workalike. The file path will be added as a
-    last parameter to the command line. 'xdg-mime' works better than the
-    traditional 'file' command, and is now the configured default (with
-    a hard-coded fallback to 'file')
-
-``processwebqueue``
-    Decide if we process the Web queue. The queue is a directory where
-    the Recoll Web browser plugins create the copies of visited pages.
-
-``textfilepagekbs``
-    Page size for text files. If this is set, text/plain files will be
-    divided into documents of approximately this size. Will reduce
-    memory usage at index time and help with loading data in the preview
-    window at query time. Particularly useful with very big files, such
-    as application or system logs. Also see textfilemaxmbs and
-    compressedfilemaxkbs.
-
-``membermaxkbs``
-    Size limit for archive members. This is passed to the filters in the
-    environment as RECOLL\_FILTER\_MAXMEMBERKB.
-
-Parameters affecting how we generate terms and organize the index
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-``indexStripChars``
-    Decide if we store character case and diacritics in the index. If we
-    do, searches sensitive to case and diacritics can be performed, but
-    the index will be bigger, and some marginal weirdness may sometimes
-    occur. The default is a stripped index. When using multiple indexes
-    for a search, this parameter must be defined identically for all.
-    Changing the value implies an index reset.
-
-``indexStoreDocText``
-    Decide if we store the documents' text content in the index. Storing
-    the text allows extracting snippets from it at query time, instead
-    of building them from index position data. Newer Xapian index
-    formats have rendered our use of positions list unacceptably slow in
-    some cases. The last Xapian index format with good performance for
-    the old method is Chert, which is default for 1.2, still supported
-    but not default in 1.4 and will be dropped in 1.6. The stored
-    document text is translated from its original format to UTF-8 plain
-    text, but not stripped of upper-case, diacritics, or punctuation
-    signs. Storing it increases the index size by 10-20% typically, but
-    also allows for nicer snippets, so it may be worth enabling it even
-    if not strictly needed for performance if you can afford the space.
-    The variable only has an effect when creating an index, meaning that
-    the xapiandb directory must not exist yet. Its exact effect depends
-    on the Xapian version. For Xapian 1.4, if the variable is set to 0,
-    the Chert format will be used, and the text will not be stored. If
-    the variable is 1, Glass will be used, and the text stored. For
-    Xapian 1.2, and for versions after 1.5 and newer, the index format
-    is always the default, but the variable controls if the text is
-    stored or not, and the abstract generation method. With Xapian 1.5
-    and later, and the variable set to 0, abstract generation may be
-    very slow, but this setting may still be useful to save space if you
-    do not use abstract generation at all.
-
-``nonumbers``
-    Decides if terms will be generated for numbers. For example "123",
-    "1.5e6", 192.168.1.4, would not be indexed if nonumbers is set
-    ("value123" would still be). Numbers are often quite interesting to
-    search for, and this should probably not be set except for special
-    situations, ie, scientific documents with huge amounts of numbers in
-    them, where setting nonumbers will reduce the index size. This can
-    only be set for a whole index, not for a subtree.
-
-``dehyphenate``
-    Determines if we index 'coworker' also when the input is
-    'co-worker'. This is new in version 1.22, and on by default. Setting
-    the variable to off allows restoring the previous behaviour.
-
-``backslashasletter``
-    Process backslash as normal letter This may make sense for people
-    wanting to index TeX commands as such but is not of much general
-    use.
-
-``maxtermlength``
-    Maximum term length. Words longer than this will be discarded. The
-    default is 40 and used to be hard-coded, but it can now be adjusted.
-    You need an index reset if you change the value.
-
-``nocjk``
-    Decides if specific East Asian (Chinese Korean Japanese)
-    characters/word splitting is turned off. This will save a small
-    amount of CPU if you have no CJK documents. If your document base
-    does include such text but you are not interested in searching it,
-    setting nocjk may be a significant time and space saver.
-
-``cjkngramlen``
-    This lets you adjust the size of n-grams used for indexing CJK text.
-    The default value of 2 is probably appropriate in most cases. A
-    value of 3 would allow more precision and efficiency on longer
-    words, but the index will be approximately twice as large.
-
-``indexstemminglanguages``
-    Languages for which to create stemming expansion data. Stemmer names
-    can be found by executing 'recollindex -l', or this can also be set
-    from a list in the GUI.
-
-``defaultcharset``
-    Default character set. This is used for files which do not contain a
-    character set definition (e.g.: text/plain). Values found inside
-    files, e.g. a 'charset' tag in HTML documents, will override it. If
-    this is not set, the default character set is the one defined by the
-    NLS environment ($LC\_ALL, $LC\_CTYPE, $LANG), or ultimately
-    iso-8859-1 (cp-1252 in fact). If for some reason you want a general
-    default which does not match your LANG and is not 8859-1, use this
-    variable. This can be redefined for any sub-directory.
-
-``unac_except_trans``
-    A list of characters, encoded in UTF-8, which should be handled
-    specially when converting text to unaccented lowercase. For example,
-    in Swedish, the letter a with diaeresis has full alphabet
-    citizenship and should not be turned into an a. Each element in the
-    space-separated list has the special character as first element and
-    the translation following. The handling of both the lowercase and
-    upper-case versions of a character should be specified, as
-    appartenance to the list will turn-off both standard accent and case
-    processing. The value is global and affects both indexing and
-    querying. Examples: Swedish: unac\_except\_trans = ää Ää öö Öö üü Üü
-    ßss œoe Œoe æae Æae ffff fifi flfl åå Åå . German: unac\_except\_trans
-    = ää Ää öö Öö üü Üü ßss œoe Œoe æae Æae ffff fifi flfl In French, you
-    probably want to decompose oe and ae and nobody would type a German
-    ß unac\_except\_trans = ßss œoe Œoe æae Æae ffff fifi flfl . The
-    default for all until someone protests follows. These decompositions
-    are not performed by unac, but it is unlikely that someone would
-    type the composed forms in a search. unac\_except\_trans = ßss œoe
-    Œoe æae Æae ffff fifi flfl
-
-``maildefcharset``
-    Overrides the default character set for email messages which don't
-    specify one. This is mainly useful for readpst (libpst) dumps, which
-    are utf-8 but do not say so.
-
-``localfields``
-    Set fields on all files (usually of a specific fs area). Syntax is
-    the usual: name = value ; attr1 = val1 ; [...] value is empty so
-    this needs an initial semi-colon. This is useful, e.g., for setting
-    the rclaptg field for application selection inside mimeview.
-
-``testmodifusemtime``
-    Use mtime instead of ctime to test if a file has been modified. The
-    time is used in addition to the size, which is always used. Setting
-    this can reduce re-indexing on systems where extended attributes are
-    used (by some other application), but not indexed, because changing
-    extended attributes only affects ctime. Notes: - This may prevent
-    detection of change in some marginal file rename cases (the target
-    would need to have the same size and mtime). - You should probably
-    also set noxattrfields to 1 in this case, except if you still prefer
-    to perform xattr indexing, for example if the local file update
-    pattern makes it of value (as in general, there is a risk for pure
-    extended attributes updates without file modification to go
-    undetected). Perform a full index reset after changing this.
-
-``noxattrfields``
-    Disable extended attributes conversion to metadata fields. This
-    probably needs to be set if testmodifusemtime is set.
-
-``metadatacmds``
-    Define commands to gather external metadata, e.g. tmsu tags. There
-    can be several entries, separated by semi-colons, each defining
-    which field name the data goes into and the command to use. Don't
-    forget the initial semi-colon. All the field names must be
-    different. You can use aliases in the "field" file if necessary. As
-    a not too pretty hack conceded to convenience, any field name
-    beginning with "rclmulti" will be taken as an indication that the
-    command returns multiple field values inside a text blob formatted
-    as a recoll configuration file ("fieldname = fieldvalue" lines). The
-    rclmultixx name will be ignored, and field names and values will be
-    parsed from the data. Example: metadatacmds = ; tags = tmsu tags %f;
-    rclmulti1 = cmdOutputsConf %f
-
-Parameters affecting where and how we store things
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-``cachedir``
-    Top directory for Recoll data. Recoll data directories are normally
-    located relative to the configuration directory (e.g.
-    ~/.recoll/xapiandb, ~/.recoll/mboxcache). If 'cachedir' is set, the
-    directories are stored under the specified value instead (e.g. if
-    cachedir is ~/.cache/recoll, the default dbdir would be
-    ~/.cache/recoll/xapiandb). This affects dbdir, webcachedir,
-    mboxcachedir, aspellDicDir, which can still be individually
-    specified to override cachedir. Note that if you have multiple
-    configurations, each must have a different cachedir, there is no
-    automatic computation of a subpath under cachedir.
-
-``maxfsoccuppc``
-    Maximum file system occupation over which we stop indexing. The
-    value is a percentage, corresponding to what the "Capacity" df
-    output column shows. The default value is 0, meaning no checking.
-
-``dbdir``
-    Xapian database directory location. This will be created on first
-    indexing. If the value is not an absolute path, it will be
-    interpreted as relative to cachedir if set, or the configuration
-    directory (-c argument or $RECOLL\_CONFDIR). If nothing is
-    specified, the default is then ~/.recoll/xapiandb/
-
-``idxstatusfile``
-    Name of the scratch file where the indexer process updates its
-    status. Default: idxstatus.txt inside the configuration directory.
-
-``mboxcachedir``
-    Directory location for storing mbox message offsets cache files.
-    This is normally 'mboxcache' under cachedir if set, or else under
-    the configuration directory, but it may be useful to share a
-    directory between different configurations.
-
-``mboxcacheminmbs``
-    Minimum mbox file size over which we cache the offsets. There is
-    really no sense in caching offsets for small files. The default is 5
-    MB.
-
-``webcachedir``
-    Directory where we store the archived web pages. This is only used
-    by the web history indexing code Default: cachedir/webcache if
-    cachedir is set, else $RECOLL\_CONFDIR/webcache
-
-``webcachemaxmbs``
-    Maximum size in MB of the Web archive. This is only used by the web
-    history indexing code. Default: 40 MB. Reducing the size will not
-    physically truncate the file.
-
-``webqueuedir``
-    The path to the Web indexing queue. This used to be hard-coded in
-    the old plugin as ~/.recollweb/ToIndex so there would be no need or
-    possibility to change it, but the WebExtensions plugin now downloads
-    the files to the user Downloads directory, and a script moves them
-    to webqueuedir. The script reads this value from the config so it
-    has become possible to change it.
-
-``webdownloadsdir``
-    The path to browser downloads directory. This is where the new
-    browser add-on extension has to create the files. They are then
-    moved by a script to webqueuedir.
-
-``aspellDicDir``
-    Aspell dictionary storage directory location. The aspell dictionary
-    (aspdict.(lang).rws) is normally stored in the directory specified
-    by cachedir if set, or under the configuration directory.
-
-``filtersdir``
-    Directory location for executable input handlers. If
-    RECOLL\_FILTERSDIR is set in the environment, we use it instead.
-    Defaults to $prefix/share/recoll/filters. Can be redefined for
-    subdirectories.
-
-``iconsdir``
-    Directory location for icons. The only reason to change this would
-    be if you want to change the icons displayed in the result list.
-    Defaults to $prefix/share/recoll/images
-
-Parameters affecting indexing performance and resource usage
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-``idxflushmb``
-    Threshold (megabytes of new data) where we flush from memory to disk
-    index. Setting this allows some control over memory usage by the
-    indexer process. A value of 0 means no explicit flushing, which lets
-    Xapian perform its own thing, meaning flushing every
-    $XAPIAN\_FLUSH\_THRESHOLD documents created, modified or deleted: as
-    memory usage depends on average document size, not only document
-    count, the Xapian approach is is not very useful, and you should let
-    Recoll manage the flushes. The program compiled value is 0. The
-    configured default value (from this file) is now 50 MB, and should
-    be ok in many cases. You can set it as low as 10 to conserve memory,
-    but if you are looking for maximum speed, you may want to experiment
-    with values between 20 and 200. In my experience, values beyond this
-    are always counterproductive. If you find otherwise, please drop me
-    a note.
-
-``filtermaxseconds``
-    Maximum external filter execution time in seconds. Default 1200
-    (20mn). Set to 0 for no limit. This is mainly to avoid infinite
-    loops in postscript files (loop.ps)
-
-``filtermaxmbytes``
-    Maximum virtual memory space for filter processes
-    (setrlimit(RLIMIT\_AS)), in megabytes. Note that this includes any
-    mapped libs (there is no reliable Linux way to limit the data space
-    only), so we need to be a bit generous here. Anything over 2000 will
-    be ignored on 32 bits machines.
-
-``thrQSizes``
-    Stage input queues configuration. There are three internal queues in
-    the indexing pipeline stages (file data extraction, terms
-    generation, index update). This parameter defines the queue depths
-    for each stage (three integer values). If a value of -1 is given for
-    a given stage, no queue is used, and the thread will go on
-    performing the next stage. In practise, deep queues have not been
-    shown to increase performance. Default: a value of 0 for the first
-    queue tells Recoll to perform autoconfiguration based on the
-    detected number of CPUs (no need for the two other values in this
-    case). Use thrQSizes = -1 -1 -1 to disable multithreading entirely.
-
-``thrTCounts``
-    Number of threads used for each indexing stage. The three stages
-    are: file data extraction, terms generation, index update). The use
-    of the counts is also controlled by some special values in
-    thrQSizes: if the first queue depth is 0, all counts are ignored
-    (autoconfigured); if a value of -1 is used for a queue depth, the
-    corresponding thread count is ignored. It makes no sense to use a
-    value other than 1 for the last stage because updating the Xapian
-    index is necessarily single-threaded (and protected by a mutex).
-
-Miscellaneous parameters
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-``loglevel``
-    Log file verbosity 1-6. A value of 2 will print only errors and
-    warnings. 3 will print information like document updates, 4 is quite
-    verbose and 6 very verbose.
-
-``logfilename``
-    Log file destination. Use 'stderr' (default) to write to the
-    console.
-
-``idxloglevel``
-    Override loglevel for the indexer.
-
-``idxlogfilename``
-    Override logfilename for the indexer.
-
-``daemloglevel``
-    Override loglevel for the indexer in real time mode. The default is
-    to use the idx... values if set, else the log... values.
-
-``daemlogfilename``
-    Override logfilename for the indexer in real time mode. The default
-    is to use the idx... values if set, else the log... values.
-
-``orgidxconfdir``
-    Original location of the configuration directory. This is used
-    exclusively for movable datasets. Locating the configuration
-    directory inside the directory tree makes it possible to provide
-    automatic query time path translations once the data set has moved
-    (for example, because it has been mounted on another location).
-
-``curidxconfdir``
-    Current location of the configuration directory. Complement
-    orgidxconfdir for movable datasets. This should be used if the
-    configuration directory has been copied from the dataset to another
-    location, either because the dataset is readonly and an r/w copy is
-    desired, or for performance reasons. This records the original moved
-    location before copy, to allow path translation computations. For
-    example if a dataset originally indexed as '/home/me/mydata/config'
-    has been mounted to '/media/me/mydata', and the GUI is running from
-    a copied configuration, orgidxconfdir would be
-    '/home/me/mydata/config', and curidxconfdir (as set in the copied
-    configuration) would be '/media/me/mydata/config'.
-
-``idxrundir``
-    Indexing process current directory. The input handlers sometimes
-    leave temporary files in the current directory, so it makes sense to
-    have recollindex chdir to some temporary directory. If the value is
-    empty, the current directory is not changed. If the value is
-    (literal) tmp, we use the temporary directory as set by the
-    environment (RECOLL\_TMPDIR else TMPDIR else /tmp). If the value is
-    an absolute path to a directory, we go there.
-
-``checkneedretryindexscript``
-    Script used to heuristically check if we need to retry indexing
-    files which previously failed. The default script checks the
-    modified dates on /usr/bin and /usr/local/bin. A relative path will
-    be looked up in the filters dirs, then in the path. Use an absolute
-    path to do otherwise.
-
-``recollhelperpath``
-    Additional places to search for helper executables. This is only
-    used on Windows for now.
-
-``idxabsmlen``
-    Length of abstracts we store while indexing. Recoll stores an
-    abstract for each indexed file. The text can come from an actual
-    'abstract' section in the document or will just be the beginning of
-    the document. It is stored in the index so that it can be displayed
-    inside the result lists without decoding the original file. The
-    idxabsmlen parameter defines the size of the stored abstract. The
-    default value is 250 bytes. The search interface gives you the
-    choice to display this stored text or a synthetic abstract built by
-    extracting text around the search terms. If you always prefer the
-    synthetic abstract, you can reduce this value and save a little
-    space.
-
-``idxmetastoredlen``
-    Truncation length of stored metadata fields. This does not affect
-    indexing (the whole field is processed anyway), just the amount of
-    data stored in the index for the purpose of displaying fields inside
-    result lists or previews. The default value is 150 bytes which may
-    be too low if you have custom fields.
-
-``idxtexttruncatelen``
-    Truncation length for all document texts. Only index the beginning
-    of documents. This is not recommended except if you are sure that
-    the interesting keywords are at the top and have severe disk space
-    issues.
-
-``aspellLanguage``
-    Language definitions to use when creating the aspell dictionary. The
-    value must match a set of aspell language definition files. You can
-    type "aspell dicts" to see a list The default if this is not set is
-    to use the NLS environment to guess the value.
-
-``aspellAddCreateParam``
-    Additional option and parameter to aspell dictionary creation
-    command. Some aspell packages may need an additional option (e.g. on
-    Debian Jessie: --local-data-dir=/usr/lib/aspell). See Debian bug
-    772415.
-
-``aspellKeepStderr``
-    Set this to have a look at aspell dictionary creation errors. There
-    are always many, so this is mostly for debugging.
-
-``noaspell``
-    Disable aspell use. The aspell dictionary generation takes time, and
-    some combinations of aspell version, language, and local terms,
-    result in aspell crashing, so it sometimes makes sense to just
-    disable the thing.
-
-``monauxinterval``
-    Auxiliary database update interval. The real time indexer only
-    updates the auxiliary databases (stemdb, aspell) periodically,
-    because it would be too costly to do it for every document change.
-    The default period is one hour.
-
-``monixinterval``
-    Minimum interval (seconds) between processings of the indexing
-    queue. The real time indexer does not process each event when it
-    comes in, but lets the queue accumulate, to diminish overhead and to
-    aggregate multiple events affecting the same file. Default 30 S.
-
-``mondelaypatterns``
-    Timing parameters for the real time indexing. Definitions for files
-    which get a longer delay before reindexing is allowed. This is for
-    fast-changing files, that should only be reindexed once in a while.
-    A list of wildcardPattern:seconds pairs. The patterns are matched
-    with fnmatch(pattern, path, 0) You can quote entries containing
-    white space with double quotes (quote the whole entry, not the
-    pattern). The default is empty. Example: mondelaypatterns =
-    \*.log:20 "\*with spaces.\*:30"
-
-``monioniceclass``
-    ionice class for the real time indexing process On platforms where
-    this is supported. The default value is 3.
-
-``monioniceclassdata``
-    ionice class parameter for the real time indexing process. On
-    platforms where this is supported. The default is empty.
-
-Query-time parameters (no impact on the index)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-``autodiacsens``
-    auto-trigger diacritics sensitivity (raw index only). IF the index
-    is not stripped, decide if we automatically trigger diacritics
-    sensitivity if the search term has accented characters (not in
-    unac\_except\_trans). Else you need to use the query language and
-    the "D" modifier to specify diacritics sensitivity. Default is no.
-
-``autocasesens``
-    auto-trigger case sensitivity (raw index only). IF the index is not
-    stripped (see indexStripChars), decide if we automatically trigger
-    character case sensitivity if the search term has upper-case
-    characters in any but the first position. Else you need to use the
-    query language and the "C" modifier to specify character-case
-    sensitivity. Default is yes.
-
-``maxTermExpand``
-    Maximum query expansion count for a single term (e.g.: when using
-    wildcards). This only affects queries, not indexing. We used to not
-    limit this at all (except for filenames where the limit was too low
-    at 1000), but it is unreasonable with a big index. Default 10000.
-
-``maxXapianClauses``
-    Maximum number of clauses we add to a single Xapian query. This only
-    affects queries, not indexing. In some cases, the result of term
-    expansion can be multiplicative, and we want to avoid eating all the
-    memory. Default 50000.
-
-``snippetMaxPosWalk``
-    Maximum number of positions we walk while populating a snippet for
-    the result list. The default of 1,000,000 may be insufficient for
-    very big documents, the consequence would be snippets with possibly
-    meaning-altering missing words.
-
-Parameters for the PDF input script
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-``pdfocr``
-    Attempt OCR of PDF files with no text content if both tesseract and
-    pdftoppm are installed. The default is off because OCR is so very
-    slow.
-
-``pdfocrlang``
-    Language to assume for PDF OCR. This is very important for having a
-    reasonable rate of errors with tesseract. This can also be set
-    through a configuration variable or directory-local parameters. See
-    the rclpdf.py script.
-
-``pdfattach``
-    Enable PDF attachment extraction by executing pdftk (if available).
-    This is normally disabled, because it does slow down PDF indexing a
-    bit even if not one attachment is ever found.
-
-``pdfextrameta``
-    Extract text from selected XMP metadata tags. This is a
-    space-separated list of qualified XMP tag names. Each element can
-    also include a translation to a Recoll field name, separated by a
-    '\|' character. If the second element is absent, the tag name is
-    used as the Recoll field names. You will also need to add
-    specifications to the 'fields' file to direct processing of the
-    extracted data.
-
-``pdfextrametafix``
-    Define name of XMP field editing script. This defines the name of a
-    script to be loaded for editing XMP field values. The script should
-    define a 'MetaFixer' class with a metafix() method which will be
-    called with the qualified tag name and value of each selected field,
-    for editing or erasing. A new instance is created for each document,
-    so that the object can keep state for, e.g. eliminating duplicate
-    values.
-
-Parameters set for specific locations
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-``mhmboxquirks``
-    Enable thunderbird/mozilla-seamonkey mbox format quirks Set this for
-    the directory where the email mbox files are stored.
-
-The fields file
-~~~~~~~~~~~~~~~
-
-This file contains information about dynamic fields handling in RCL.
-Some very basic fields have hard-wired behaviour, and, mostly, you
-should not change the original data inside the ``fields`` file. But you
-can create custom fields fitting your data and handle them just like
-they were native ones.
-
-The ``fields`` file has several sections, which each define an aspect of
-fields processing. Quite often, you'll have to modify several sections
-to obtain the desired behaviour.
-
-We will only give a short description here, you should refer to the
-comments inside the default file for more detailed information.
-
-Field names should be lowercase alphabetic ASCII.
-
-[prefixes]
-    A field becomes indexed (searchable) by having a prefix defined in
-    this section. There is a more complete explanation of what prefixes
-    are in used by a standard recoll installation. In a nutshell:
-    extension prefixes should be all caps, begin with XY, and short.
-    E.g. XYMFLD.
-
-[values]
-    Fields listed in this section will be stored as XAP ``values``
-    inside the index. This makes them available for range queries,
-    allowing to filter results according to the field value. This
-    feature currently supports string and integer data. See the comments
-    in the file for more detail
-
-[stored]
-    A field becomes stored (displayable inside results) by having its
-    name listed in this section (typically with an empty value).
-
-[aliases]
-    This section defines lists of synonyms for the canonical names used
-    inside the ``[prefixes]`` and ``[stored]`` sections
-
-[queryaliases]
-    This section also defines aliases for the canonic field names, with
-    the difference that the substitution will only be used at query
-    time, avoiding any possibility that the value would pick-up random
-    metadata from documents.
-
-handler-specific sections
-    Some input handlers may need specific configuration for handling
-    fields. Only the email message handler currently has such a section
-    (named ``[mail]``). It allows indexing arbitrary email headers in
-    addition to the ones indexed by default. Other such sections may
-    appear in the future.
-
-Here follows a small example of a personal ``fields`` file. This would
-extract a specific email header and use it as a searchable field, with
-data displayable inside result lists. (Side note: as the email handler
-does no decoding on the values, only plain ascii headers can be indexed,
-and only the first occurrence will be used for headers that occur
-several times).
-
-::
-
-    [prefixes]
-            # Index mailmytag contents (with the given prefix)
-            mailmytag = XMTAG
-
-            [stored]
-            # Store mailmytag inside the document data record (so that it can be
-            # displayed - as %(mailmytag) - in result lists).
-            mailmytag = 
-
-            [queryaliases]
-            filename = fn
-            containerfilename = cfn
-
-            [mail]
-            # Extract the X-My-Tag mail header, and use it internally with the
-            # mailmytag field name
-            x-my-tag = mailmytag
-            
-
-Extended attributes in the fields file
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-RCL versions 1.19 and later process user extended file attributes as
-documents fields by default.
-
-Attributes are processed as fields of the same name, after removing the
-``user`` prefix on Linux.
-
-The ``[xattrtofields]`` section of the ``fields`` file allows specifying
-translations from extended attributes names to RCL field names. An empty
-translation disables use of the corresponding attribute data.
-
-The mimemap file
-~~~~~~~~~~~~~~~~
-
-``mimemap`` specifies the file name extension to MIME type mappings.
-
-For file names without an extension, or with an unknown one, a system
-command (``file`` ``-i``, or ``xdg-mime``) will be executed to determine
-the MIME type (this can be switched off, or the command changed inside
-the main configuration file).
-
-All extension values in ``mimemap`` must be entered in lower case. File
-names extensions are lower-cased for comparison during indexing, meaning
-that an upper case ``mimemap`` entry will never be matched.
-
-The mappings can be specified on a per-subtree basis, which may be
-useful in some cases. Example: okular notes have a ``.xml`` extension
-but should be handled specially, which is possible because they are
-usually all located in one place. Example:
-
-::
-
-    [~/.kde/share/apps/okular/docdata]
-            .xml = application/x-okular-notes
-
-The ``recoll_noindex`` ``mimemap`` variable has been moved to
-``recoll.conf`` and renamed to ``noContentSuffixes``, while keeping the
-same function, as of RCL version 1.21. For older RCL versions, see the
-documentation for ``noContentSuffixes`` but use ``recoll_noindex`` in
-``mimemap``.
-
-The mimeconf file
-~~~~~~~~~~~~~~~~~
-
-The main purpose of the ``mimeconf`` file is to specify how the
-different MIME types are handled for indexing. This is done in the
-``[index]`` section, which should not be modified casually. See the
-comments in the file.
-
-The file also contains other definitions which affect the query language
-and the GUI, and which, in retrospect, should have been stored
-elsewhere.
-
-The ``[icons]`` section allows you to change the icons which are
-displayed by the ``recoll`` GUI in the result lists (the values are the
-basenames of the ``png`` images inside the ``iconsdir`` directory (which
-is itself defined in ``recoll.conf``).
-
-The ``[categories]`` section defines the groupings of MIME types into
-``categories`` as used when adding an ``rclcat`` clause to a `query
-language <#RCL.SEARCH.LANG>`__ query. ``rclcat`` clauses are also used
-by the default ``guifilters`` buttons in the GUI (see next).
-
-The filter controls appear at the top of the ``recoll`` GUI, either as
-checkboxes just above the result list, or as a dropbox in the tool area.
-
-By default, they are labeled: ``media``, ``message``, ``other``,
-``presentation``, ``spreadsheet`` and ``text``, and each maps to a
-document category. This is determined in the ``[guifilters]`` section,
-where each control is defined by a variable naming a query language
-fragment.
-
-A simple exemple will hopefully make things clearer.
-
-::
-
-    [guifilters]
-
-    Big Books = dir:"~/My Books" size>10K
-    My Docs = dir:"~/My Documents"
-    Small Books = dir:"~/My Books" size<10K
-    System Docs = dir:/usr/share/doc
-            
-
-The above definition would create four filter checkboxes, labelled
-``Big Books``, ``My Docs``, etc.
-
-The text after the equal sign must be a valid query language fragment,
-and, when the button is checked, it will be combined with the rest of
-the query with an AND conjunction.
-
-Any name text before a colon character will be erased in the display,
-but used for sorting. You can use this to display the checkboxes in any
-order you like. For exemple, the following would do exactly the same as
-above, but ordering the checkboxes in the reverse order.
-
-::
-
-    [guifilters]
-
-    d:Big Books = dir:"~/My Books" size>10K
-    c:My Docs = dir:"~/My Documents"
-    b:Small Books = dir:"~/My Books" size<10K
-    a:System Docs = dir:/usr/share/doc
-            
-
-As you may have guessed, The default ``[guifilters]`` section looks
-like:
-
-::
-
-    [guifilters]
-    text = rclcat:text
-    spreadsheet = rclcat:spreadsheet
-    presentation = rclcat:presentation
-    media = rclcat:media
-    message = rclcat:message
-    other = rclcat:other
-            
-
-The mimeview file
-~~~~~~~~~~~~~~~~~
-
-``mimeview`` specifies which programs are started when you click on an
-Open link in a result list. Ie: HTML is normally displayed using
-firefox, but you may prefer Konqueror, your openoffice.org program might
-be named ``oofice`` instead of ``openoffice`` etc.
-
-Changes to this file can be done by direct editing, or through the
-``recoll`` GUI preferences dialog.
-
-If Use desktop preferences to choose document editor is checked in the
-RCL GUI preferences, all ``mimeview`` entries will be ignored except the
-one labelled ``application/x-all`` (which is set to use ``xdg-open`` by
-default).
-
-In this case, the ``xallexcepts`` top level variable defines a list of
-MIME type exceptions which will be processed according to the local
-entries instead of being passed to the desktop. This is so that specific
-RCL options such as a page number or a search string can be passed to
-applications that support them, such as the evince viewer.
-
-As for the other configuration files, the normal usage is to have a
-``mimeview`` inside your own configuration directory, with just the
-non-default entries, which will override those from the central
-configuration file.
-
-All viewer definition entries must be placed under a ``[view]`` section.
-
-The keys in the file are normally MIME types. You can add an application
-tag to specialize the choice for an area of the filesystem (using a
-``localfields`` specification in ``mimeconf``). The syntax for the key
-is mimetype\ ``|``\ tag
-
-The ``nouncompforviewmts`` entry, (placed at the top level, outside of
-the ``[view]`` section), holds a list of MIME types that should not be
-uncompressed before starting the viewer (if they are found compressed,
-ie: mydoc.doc.gz).
-
-The right side of each assignment holds a command to be executed for
-opening the file. The following substitutions are performed:
-
--  **%D.**
-
-   Document date
-
--  **%f.**
-
-   File name. This may be the name of a temporary file if it was
-   necessary to create one (ie: to extract a subdocument from a
-   container).
-
--  **%i.**
-
-   Internal path, for subdocuments of containers. The format depends on
-   the container type. If this appears in the command line, RCL will not
-   create a temporary file to extract the subdocument, expecting the
-   called application (possibly a script) to be able to handle it.
-
--  **%M.**
-
-   MIME type
-
--  **%p.**
-
-   Page index. Only significant for a subset of document types,
-   currently only PDF, Postscript and DVI files. Can be used to start
-   the editor at the right page for a match or snippet.
-
--  **%s.**
-
-   Search term. The value will only be set for documents with indexed
-   page numbers (ie: PDF). The value will be one of the matched search
-   terms. It would allow pre-setting the value in the "Find" entry
-   inside Evince for example, for easy highlighting of the term.
-
--  **%u.**
-
-   Url.
-
-In addition to the predefined values above, all strings like
-``%(fieldname)`` will be replaced by the value of the field named
-``fieldname`` for the document. This could be used in combination with
-field customisation to help with opening the document.
-
-The ``ptrans`` file
-~~~~~~~~~~~~~~~~~~~
-
-``ptrans`` specifies query-time path translations. These can be useful
-in `multiple cases <#RCL.SEARCH.PTRANS>`__.
-
-The file has a section for any index which needs translations, either
-the main one or additional query indexes. The sections are named with
-the XAP index directory names. No slash character should exist at the
-end of the paths (all comparisons are textual). An exemple should make
-things sufficiently clear
-
-::
-
-              [/home/me/.recoll/xapiandb]
-              /this/directory/moved = /to/this/place
-
-              [/path/to/additional/xapiandb]
-              /server/volume1/docdir = /net/server/volume1/docdir
-              /server/volume2/docdir = /net/server/volume2/docdir
-            
-
-Examples of configuration adjustments
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Adding an external viewer for an non-indexed type
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Imagine that you have some kind of file which does not have indexable
-content, but for which you would like to have a functional Open link in
-the result list (when found by file name). The file names end in .blob
-and can be displayed by application blobviewer.
-
-You need two entries in the configuration files for this to work:
-
--  In ``$RECOLL_CONFDIR/mimemap`` (typically ``~/.recoll/mimemap``), add
-   the following line:
-
-   ::
-
-                   .blob = application/x-blobapp
-                 
-
-   Note that the MIME type is made up here, and you could call it
-   diesel/oil just the same.
-
--  In ``$RECOLL_CONFDIR/mimeview`` under the ``[view]`` section, add:
-
-   ::
-
-                     application/x-blobapp = blobviewer %f
-                   
-
-   We are supposing that blobviewer wants a file name parameter here,
-   you would use ``%u`` if it liked URLs better.
-
-If you just wanted to change the application used by RCL to display a
-MIME type which it already knows, you would just need to edit
-``mimeview``. The entries you add in your personal file override those
-in the central configuration, which you do not need to alter.
-``mimeview`` can also be modified from the Gui.
-
-Adding indexing support for a new file type
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Let us now imagine that the above .blob files actually contain indexable
-text and that you know how to extract it with a command line program.
-Getting RCL to index the files is easy. You need to perform the above
-alteration, and also to add data to the ``mimeconf`` file (typically in
-``~/.recoll/mimeconf``):
-
--  Under the ``[index]`` section, add the following line (more about the
-   rclblob indexing script later):
-
-   ::
-
-       application/x-blobapp = exec rclblob
-
-   Or if the files are mostly text and you don't need to process them
-   for indexing:
-
-   ::
-
-       application/x-blobapp = internal text/plain
-
--  Under the ``[icons]`` section, you should choose an icon to be
-   displayed for the files inside the result lists. Icons are normally
-   64x64 pixels PNG files which live in ``/usr/share/recoll/images``.
-
--  Under the ``[categories]`` section, you should add the MIME type
-   where it makes sense (you can also create a category). Categories may
-   be used for filtering in advanced search.
-
-The rclblob handler should be an executable program or script which
-exists inside ``/usr/share/recoll/filters``. It will be given a file
-name as argument and should output the text or html contents on the
-standard output.
-
-The `filter programming <#RCL.PROGRAM.FILTERS>`__ section describes in
-more detail how to write an input handler.
diff --git a/src/doc/user/sphinx/_build/html/_static/ajax-loader.gif b/src/doc/user/sphinx/_build/html/_static/ajax-loader.gif
deleted file mode 100644
index 61faf8cab23993bd3e1560bff0668bd628642330..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 673
zcmZ?wbhEHb6krfw_{6~Q|Nno%(3)e{?)x>&1u}A`t?OF7Z|1gRivOgXi&7IyQd1Pl
zGfOfQ60;I3a`F>X^fL3(@);C=vM_KlFfb_o=k{|A33hf2a5d61U}gjg=>Rd%XaNQW
zW@Cw{|b%Y*pl8F?4B9
zlo4Fz*0kZGJabY|>}Okf0}CCg{u4`zEPY^pV?j2@h+|igy0+Kz6p;@SpM4s6)XEMg
z#3Y4GX>Hjlml5ftdH$4x0JGdn8~MX(U~_^d!Hi)=HU{V%g+mi8#UGbE-*ao8f#h+S
z2a0-5+vc7MU$e-NhmBjLIC1v|)9+Im8x1yacJ7{^tLX(ZhYi^rpmXm0`@ku9b53aN
zEXH@Y3JaztblgpxbJt{AtE1ad1Ca>{v$rwwvK(>{m~Gf_=-Ro7Fk{#;i~+{{>QtvI
yb2P8Zac~?~=sRA>$6{!(^3;ZP0TPFR(G_-UDU(8Jl0?(IXu$~#4A!880|o%~Al1tN

diff --git a/src/doc/user/sphinx/_build/html/_static/alabaster.css b/src/doc/user/sphinx/_build/html/_static/alabaster.css
deleted file mode 100644
index 517cb43e..00000000
--- a/src/doc/user/sphinx/_build/html/_static/alabaster.css
+++ /dev/null
@@ -1,607 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-@import url("basic.css");
-
-/* -- page layout ----------------------------------------------------------- */
-
-body {
-    font-family: 'goudy old style', 'minion pro', 'bell mt', Georgia, 'Hiragino Mincho Pro', serif;
-    font-size: 17px;
-    background-color: white;
-    color: #000;
-    margin: 0;
-    padding: 0;
-}
-
-
-div.document {
-    width: 940px;
-    margin: 30px auto 0 auto;
-}
-
-div.documentwrapper {
-    float: left;
-    width: 100%;
-}
-
-div.bodywrapper {
-    margin: 0 0 0 220px;
-}
-
-div.sphinxsidebar {
-    width: 220px;
-    font-size: 14px;
-    line-height: 1.5;
-}
-
-hr {
-    border: 1px solid #B1B4B6;
-}
-
-div.body {
-    background-color: #ffffff;
-    color: #3E4349;
-    padding: 0 30px 0 30px;
-}
-
-div.body > .section {
-    text-align: left;
-}
-
-div.footer {
-    width: 940px;
-    margin: 20px auto 30px auto;
-    font-size: 14px;
-    color: #888;
-    text-align: right;
-}
-
-div.footer a {
-    color: #888;
-}
-
-p.caption {
-    font-family: ;
-    font-size: inherit;
-}
-
-
-div.relations {
-    display: none;
-}
-
-
-div.sphinxsidebar a {
-    color: #444;
-    text-decoration: none;
-    border-bottom: 1px dotted #999;
-}
-
-div.sphinxsidebar a:hover {
-    border-bottom: 1px solid #999;
-}
-
-div.sphinxsidebarwrapper {
-    padding: 18px 10px;
-}
-
-div.sphinxsidebarwrapper p.logo {
-    padding: 0;
-    margin: -10px 0 0 0px;
-    text-align: center;
-}
-
-div.sphinxsidebarwrapper h1.logo {
-    margin-top: -10px;
-    text-align: center;
-    margin-bottom: 5px;
-    text-align: left;
-}
-
-div.sphinxsidebarwrapper h1.logo-name {
-    margin-top: 0px;
-}
-
-div.sphinxsidebarwrapper p.blurb {
-    margin-top: 0;
-    font-style: normal;
-}
-
-div.sphinxsidebar h3,
-div.sphinxsidebar h4 {
-    font-family: 'Garamond', 'Georgia', serif;
-    color: #444;
-    font-size: 24px;
-    font-weight: normal;
-    margin: 0 0 5px 0;
-    padding: 0;
-}
-
-div.sphinxsidebar h4 {
-    font-size: 20px;
-}
-
-div.sphinxsidebar h3 a {
-    color: #444;
-}
-
-div.sphinxsidebar p.logo a,
-div.sphinxsidebar h3 a,
-div.sphinxsidebar p.logo a:hover,
-div.sphinxsidebar h3 a:hover {
-    border: none;
-}
-
-div.sphinxsidebar p {
-    color: #555;
-    margin: 10px 0;
-}
-
-div.sphinxsidebar ul {
-    margin: 10px 0;
-    padding: 0;
-    color: #000;
-}
-
-div.sphinxsidebar ul li.toctree-l1 > a {
-    font-size: 120%;
-}
-
-div.sphinxsidebar ul li.toctree-l2 > a {
-    font-size: 110%;
-}
-
-div.sphinxsidebar input {
-    border: 1px solid #CCC;
-    font-family: 'goudy old style', 'minion pro', 'bell mt', Georgia, 'Hiragino Mincho Pro', serif;
-    font-size: 1em;
-}
-
-div.sphinxsidebar hr {
-    border: none;
-    height: 1px;
-    color: #AAA;
-    background: #AAA;
-
-    text-align: left;
-    margin-left: 0;
-    width: 50%;
-}
-
-/* -- body styles ----------------------------------------------------------- */
-
-a {
-    color: #004B6B;
-    text-decoration: underline;
-}
-
-a:hover {
-    color: #6D4100;
-    text-decoration: underline;
-}
-
-div.body h1,
-div.body h2,
-div.body h3,
-div.body h4,
-div.body h5,
-div.body h6 {
-    font-family: 'Garamond', 'Georgia', serif;
-    font-weight: normal;
-    margin: 30px 0px 10px 0px;
-    padding: 0;
-}
-
-div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; }
-div.body h2 { font-size: 180%; }
-div.body h3 { font-size: 150%; }
-div.body h4 { font-size: 130%; }
-div.body h5 { font-size: 100%; }
-div.body h6 { font-size: 100%; }
-
-a.headerlink {
-    color: #DDD;
-    padding: 0 4px;
-    text-decoration: none;
-}
-
-a.headerlink:hover {
-    color: #444;
-    background: #EAEAEA;
-}
-
-div.body p, div.body dd, div.body li {
-    line-height: 1.4em;
-}
-
-div.admonition {
-    margin: 20px 0px;
-    padding: 10px 30px;
-    background-color: #FCC;
-    border: 1px solid #FAA;
-}
-
-div.admonition tt.xref, div.admonition a tt {
-    border-bottom: 1px solid #fafafa;
-}
-
-dd div.admonition {
-    margin-left: -60px;
-    padding-left: 60px;
-}
-
-div.admonition p.admonition-title {
-    font-family: 'Garamond', 'Georgia', serif;
-    font-weight: normal;
-    font-size: 24px;
-    margin: 0 0 10px 0;
-    padding: 0;
-    line-height: 1;
-}
-
-div.admonition p.last {
-    margin-bottom: 0;
-}
-
-div.highlight {
-    background-color: white;
-}
-
-dt:target, .highlight {
-    background: #FAF3E8;
-}
-
-div.note {
-    background-color: #EEE;
-    border: 1px solid #CCC;
-}
-
-div.seealso {
-    background-color: #EEE;
-    border: 1px solid #CCC;
-}
-
-div.topic {
-    background-color: #eee;
-}
-
-p.admonition-title {
-    display: inline;
-}
-
-p.admonition-title:after {
-    content: ":";
-}
-
-pre, tt, code {
-    font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
-    font-size: 0.9em;
-}
-
-.hll {
-    background-color: #FFC;
-    margin: 0 -12px;
-    padding: 0 12px;
-    display: block;
-}
-
-img.screenshot {
-}
-
-tt.descname, tt.descclassname, code.descname, code.descclassname {
-    font-size: 0.95em;
-}
-
-tt.descname, code.descname {
-    padding-right: 0.08em;
-}
-
-img.screenshot {
-    -moz-box-shadow: 2px 2px 4px #eee;
-    -webkit-box-shadow: 2px 2px 4px #eee;
-    box-shadow: 2px 2px 4px #eee;
-}
-
-table.docutils {
-    border: 1px solid #888;
-    -moz-box-shadow: 2px 2px 4px #eee;
-    -webkit-box-shadow: 2px 2px 4px #eee;
-    box-shadow: 2px 2px 4px #eee;
-}
-
-table.docutils td, table.docutils th {
-    border: 1px solid #888;
-    padding: 0.25em 0.7em;
-}
-
-table.field-list, table.footnote {
-    border: none;
-    -moz-box-shadow: none;
-    -webkit-box-shadow: none;
-    box-shadow: none;
-}
-
-table.footnote {
-    margin: 15px 0;
-    width: 100%;
-    border: 1px solid #EEE;
-    background: #FDFDFD;
-    font-size: 0.9em;
-}
-
-table.footnote + table.footnote {
-    margin-top: -15px;
-    border-top: none;
-}
-
-table.field-list th {
-    padding: 0 0.8em 0 0;
-}
-
-table.field-list td {
-    padding: 0;
-}
-
-table.field-list p {
-    margin-bottom: 0.8em;
-}
-
-table.footnote td.label {
-    width: .1px;
-    padding: 0.3em 0 0.3em 0.5em;
-}
-
-table.footnote td {
-    padding: 0.3em 0.5em;
-}
-
-dl {
-    margin: 0;
-    padding: 0;
-}
-
-dl dd {
-    margin-left: 30px;
-}
-
-blockquote {
-    margin: 0 0 0 30px;
-    padding: 0;
-}
-
-ul, ol {
-    /* Matches the 30px from the narrow-screen "li > ul" selector below */
-    margin: 10px 0 10px 30px;
-    padding: 0;
-}
-
-pre {
-    background: #EEE;
-    padding: 7px 30px;
-    margin: 15px 0px;
-    line-height: 1.3em;
-}
-
-dl pre, blockquote pre, li pre {
-    margin-left: 0;
-    padding-left: 30px;
-}
-
-dl dl pre {
-    margin-left: -90px;
-    padding-left: 90px;
-}
-
-tt, code {
-    background-color: #ecf0f3;
-    color: #222;
-    /* padding: 1px 2px; */
-}
-
-tt.xref, code.xref, a tt {
-    background-color: #FBFBFB;
-    border-bottom: 1px solid white;
-}
-
-a.reference {
-    text-decoration: none;
-    border-bottom: 1px dotted #004B6B;
-}
-
-/* Don't put an underline on images */
-a.image-reference, a.image-reference:hover {
-    border-bottom: none;
-}
-
-a.reference:hover {
-    border-bottom: 1px solid #6D4100;
-}
-
-a.footnote-reference {
-    text-decoration: none;
-    font-size: 0.7em;
-    vertical-align: top;
-    border-bottom: 1px dotted #004B6B;
-}
-
-a.footnote-reference:hover {
-    border-bottom: 1px solid #6D4100;
-}
-
-a:hover tt, a:hover code {
-    background: #EEE;
-}
-
-
-@media screen and (max-width: 870px) {
-
-    div.sphinxsidebar {
-    	display: none;
-    }
-
-    div.document {
-       width: 100%;
-
-    }
-
-    div.documentwrapper {
-    	margin-left: 0;
-    	margin-top: 0;
-    	margin-right: 0;
-    	margin-bottom: 0;
-    }
-
-    div.bodywrapper {
-    	margin-top: 0;
-    	margin-right: 0;
-    	margin-bottom: 0;
-    	margin-left: 0;
-    }
-
-    ul {
-    	margin-left: 0;
-    }
-
-	li > ul {
-        /* Matches the 30px from the "ul, ol" selector above */
-		margin-left: 30px;
-	}
-
-    .document {
-    	width: auto;
-    }
-
-    .footer {
-    	width: auto;
-    }
-
-    .bodywrapper {
-    	margin: 0;
-    }
-
-    .footer {
-    	width: auto;
-    }
-
-    .github {
-        display: none;
-    }
-
-
-
-}
-
-
-
-@media screen and (max-width: 875px) {
-
-    body {
-        margin: 0;
-        padding: 20px 30px;
-    }
-
-    div.documentwrapper {
-        float: none;
-        background: white;
-    }
-
-    div.sphinxsidebar {
-        display: block;
-        float: none;
-        width: 102.5%;
-        margin: 50px -30px -20px -30px;
-        padding: 10px 20px;
-        background: #333;
-        color: #FFF;
-    }
-
-    div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p,
-    div.sphinxsidebar h3 a {
-        color: white;
-    }
-
-    div.sphinxsidebar a {
-        color: #AAA;
-    }
-
-    div.sphinxsidebar p.logo {
-        display: none;
-    }
-
-    div.document {
-        width: 100%;
-        margin: 0;
-    }
-
-    div.footer {
-        display: none;
-    }
-
-    div.bodywrapper {
-        margin: 0;
-    }
-
-    div.body {
-        min-height: 0;
-        padding: 0;
-    }
-
-    .rtd_doc_footer {
-        display: none;
-    }
-
-    .document {
-        width: auto;
-    }
-
-    .footer {
-        width: auto;
-    }
-
-    .footer {
-        width: auto;
-    }
-
-    .github {
-        display: none;
-    }
-}
-
-
-/* misc. */
-
-.revsys-inline {
-    display: none!important;
-}
-
-/* Make nested-list/multi-paragraph items look better in Releases changelog
- * pages. Without this, docutils' magical list fuckery causes inconsistent
- * formatting between different release sub-lists.
- */
-div#changelog > div.section > ul > li > p:only-child {
-    margin-bottom: 0;
-}
-
-/* Hide fugly table cell borders in ..bibliography:: directive output */
-table.docutils.citation, table.docutils.citation td, table.docutils.citation th {
-  border: none;
-  /* Below needed in some edge cases; if not applied, bottom shadows appear */
-  -moz-box-shadow: none;
-  -webkit-box-shadow: none;
-  box-shadow: none;
-}
\ No newline at end of file
diff --git a/src/doc/user/sphinx/_build/html/_static/basic.css b/src/doc/user/sphinx/_build/html/_static/basic.css
deleted file mode 100644
index 0b79414a..00000000
--- a/src/doc/user/sphinx/_build/html/_static/basic.css
+++ /dev/null
@@ -1,611 +0,0 @@
-/*
- * basic.css
- * ~~~~~~~~~
- *
- * Sphinx stylesheet -- basic theme.
- *
- * :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
- * :license: BSD, see LICENSE for details.
- *
- */
-
-/* -- main layout ----------------------------------------------------------- */
-
-div.clearer {
-    clear: both;
-}
-
-/* -- relbar ---------------------------------------------------------------- */
-
-div.related {
-    width: 100%;
-    font-size: 90%;
-}
-
-div.related h3 {
-    display: none;
-}
-
-div.related ul {
-    margin: 0;
-    padding: 0 0 0 10px;
-    list-style: none;
-}
-
-div.related li {
-    display: inline;
-}
-
-div.related li.right {
-    float: right;
-    margin-right: 5px;
-}
-
-/* -- sidebar --------------------------------------------------------------- */
-
-div.sphinxsidebarwrapper {
-    padding: 10px 5px 0 10px;
-}
-
-div.sphinxsidebar {
-    float: left;
-    width: 230px;
-    margin-left: -100%;
-    font-size: 90%;
-    word-wrap: break-word;
-    overflow-wrap : break-word;
-}
-
-div.sphinxsidebar ul {
-    list-style: none;
-}
-
-div.sphinxsidebar ul ul,
-div.sphinxsidebar ul.want-points {
-    margin-left: 20px;
-    list-style: square;
-}
-
-div.sphinxsidebar ul ul {
-    margin-top: 0;
-    margin-bottom: 0;
-}
-
-div.sphinxsidebar form {
-    margin-top: 10px;
-}
-
-div.sphinxsidebar input {
-    border: 1px solid #98dbcc;
-    font-family: sans-serif;
-    font-size: 1em;
-}
-
-div.sphinxsidebar #searchbox input[type="text"] {
-    width: 170px;
-}
-
-img {
-    border: 0;
-    max-width: 100%;
-}
-
-/* -- search page ----------------------------------------------------------- */
-
-ul.search {
-    margin: 10px 0 0 20px;
-    padding: 0;
-}
-
-ul.search li {
-    padding: 5px 0 5px 20px;
-    background-image: url(file.png);
-    background-repeat: no-repeat;
-    background-position: 0 7px;
-}
-
-ul.search li a {
-    font-weight: bold;
-}
-
-ul.search li div.context {
-    color: #888;
-    margin: 2px 0 0 30px;
-    text-align: left;
-}
-
-ul.keywordmatches li.goodmatch a {
-    font-weight: bold;
-}
-
-/* -- index page ------------------------------------------------------------ */
-
-table.contentstable {
-    width: 90%;
-}
-
-table.contentstable p.biglink {
-    line-height: 150%;
-}
-
-a.biglink {
-    font-size: 1.3em;
-}
-
-span.linkdescr {
-    font-style: italic;
-    padding-top: 5px;
-    font-size: 90%;
-}
-
-/* -- general index --------------------------------------------------------- */
-
-table.indextable {
-    width: 100%;
-}
-
-table.indextable td {
-    text-align: left;
-    vertical-align: top;
-}
-
-table.indextable dl, table.indextable dd {
-    margin-top: 0;
-    margin-bottom: 0;
-}
-
-table.indextable tr.pcap {
-    height: 10px;
-}
-
-table.indextable tr.cap {
-    margin-top: 10px;
-    background-color: #f2f2f2;
-}
-
-img.toggler {
-    margin-right: 3px;
-    margin-top: 3px;
-    cursor: pointer;
-}
-
-div.modindex-jumpbox {
-    border-top: 1px solid #ddd;
-    border-bottom: 1px solid #ddd;
-    margin: 1em 0 1em 0;
-    padding: 0.4em;
-}
-
-div.genindex-jumpbox {
-    border-top: 1px solid #ddd;
-    border-bottom: 1px solid #ddd;
-    margin: 1em 0 1em 0;
-    padding: 0.4em;
-}
-
-/* -- general body styles --------------------------------------------------- */
-
-div.body p, div.body dd, div.body li, div.body blockquote {
-    -moz-hyphens: auto;
-    -ms-hyphens: auto;
-    -webkit-hyphens: auto;
-    hyphens: auto;
-}
-
-a.headerlink {
-    visibility: hidden;
-}
-
-h1:hover > a.headerlink,
-h2:hover > a.headerlink,
-h3:hover > a.headerlink,
-h4:hover > a.headerlink,
-h5:hover > a.headerlink,
-h6:hover > a.headerlink,
-dt:hover > a.headerlink,
-caption:hover > a.headerlink,
-p.caption:hover > a.headerlink,
-div.code-block-caption:hover > a.headerlink {
-    visibility: visible;
-}
-
-div.body p.caption {
-    text-align: inherit;
-}
-
-div.body td {
-    text-align: left;
-}
-
-.field-list ul {
-    padding-left: 1em;
-}
-
-.first {
-    margin-top: 0 !important;
-}
-
-p.rubric {
-    margin-top: 30px;
-    font-weight: bold;
-}
-
-img.align-left, .figure.align-left, object.align-left {
-    clear: left;
-    float: left;
-    margin-right: 1em;
-}
-
-img.align-right, .figure.align-right, object.align-right {
-    clear: right;
-    float: right;
-    margin-left: 1em;
-}
-
-img.align-center, .figure.align-center, object.align-center {
-  display: block;
-  margin-left: auto;
-  margin-right: auto;
-}
-
-.align-left {
-    text-align: left;
-}
-
-.align-center {
-    text-align: center;
-}
-
-.align-right {
-    text-align: right;
-}
-
-/* -- sidebars -------------------------------------------------------------- */
-
-div.sidebar {
-    margin: 0 0 0.5em 1em;
-    border: 1px solid #ddb;
-    padding: 7px 7px 0 7px;
-    background-color: #ffe;
-    width: 40%;
-    float: right;
-}
-
-p.sidebar-title {
-    font-weight: bold;
-}
-
-/* -- topics ---------------------------------------------------------------- */
-
-div.topic {
-    border: 1px solid #ccc;
-    padding: 7px 7px 0 7px;
-    margin: 10px 0 10px 0;
-}
-
-p.topic-title {
-    font-size: 1.1em;
-    font-weight: bold;
-    margin-top: 10px;
-}
-
-/* -- admonitions ----------------------------------------------------------- */
-
-div.admonition {
-    margin-top: 10px;
-    margin-bottom: 10px;
-    padding: 7px;
-}
-
-div.admonition dt {
-    font-weight: bold;
-}
-
-div.admonition dl {
-    margin-bottom: 0;
-}
-
-p.admonition-title {
-    margin: 0px 10px 5px 0px;
-    font-weight: bold;
-}
-
-div.body p.centered {
-    text-align: center;
-    margin-top: 25px;
-}
-
-/* -- tables ---------------------------------------------------------------- */
-
-table.docutils {
-    border: 0;
-    border-collapse: collapse;
-}
-
-table caption span.caption-number {
-    font-style: italic;
-}
-
-table caption span.caption-text {
-}
-
-table.docutils td, table.docutils th {
-    padding: 1px 8px 1px 5px;
-    border-top: 0;
-    border-left: 0;
-    border-right: 0;
-    border-bottom: 1px solid #aaa;
-}
-
-table.field-list td, table.field-list th {
-    border: 0 !important;
-}
-
-table.footnote td, table.footnote th {
-    border: 0 !important;
-}
-
-th {
-    text-align: left;
-    padding-right: 5px;
-}
-
-table.citation {
-    border-left: solid 1px gray;
-    margin-left: 1px;
-}
-
-table.citation td {
-    border-bottom: none;
-}
-
-/* -- figures --------------------------------------------------------------- */
-
-div.figure {
-    margin: 0.5em;
-    padding: 0.5em;
-}
-
-div.figure p.caption {
-    padding: 0.3em;
-}
-
-div.figure p.caption span.caption-number {
-    font-style: italic;
-}
-
-div.figure p.caption span.caption-text {
-}
-
-
-/* -- other body styles ----------------------------------------------------- */
-
-ol.arabic {
-    list-style: decimal;
-}
-
-ol.loweralpha {
-    list-style: lower-alpha;
-}
-
-ol.upperalpha {
-    list-style: upper-alpha;
-}
-
-ol.lowerroman {
-    list-style: lower-roman;
-}
-
-ol.upperroman {
-    list-style: upper-roman;
-}
-
-dl {
-    margin-bottom: 15px;
-}
-
-dd p {
-    margin-top: 0px;
-}
-
-dd ul, dd table {
-    margin-bottom: 10px;
-}
-
-dd {
-    margin-top: 3px;
-    margin-bottom: 10px;
-    margin-left: 30px;
-}
-
-dt:target, .highlighted {
-    background-color: #fbe54e;
-}
-
-dl.glossary dt {
-    font-weight: bold;
-    font-size: 1.1em;
-}
-
-.field-list ul {
-    margin: 0;
-    padding-left: 1em;
-}
-
-.field-list p {
-    margin: 0;
-}
-
-.optional {
-    font-size: 1.3em;
-}
-
-.sig-paren {
-    font-size: larger;
-}
-
-.versionmodified {
-    font-style: italic;
-}
-
-.system-message {
-    background-color: #fda;
-    padding: 5px;
-    border: 3px solid red;
-}
-
-.footnote:target  {
-    background-color: #ffa;
-}
-
-.line-block {
-    display: block;
-    margin-top: 1em;
-    margin-bottom: 1em;
-}
-
-.line-block .line-block {
-    margin-top: 0;
-    margin-bottom: 0;
-    margin-left: 1.5em;
-}
-
-.guilabel, .menuselection {
-    font-family: sans-serif;
-}
-
-.accelerator {
-    text-decoration: underline;
-}
-
-.classifier {
-    font-style: oblique;
-}
-
-abbr, acronym {
-    border-bottom: dotted 1px;
-    cursor: help;
-}
-
-/* -- code displays --------------------------------------------------------- */
-
-pre {
-    overflow: auto;
-    overflow-y: hidden;  /* fixes display issues on Chrome browsers */
-}
-
-span.pre {
-    -moz-hyphens: none;
-    -ms-hyphens: none;
-    -webkit-hyphens: none;
-    hyphens: none;
-}
-
-td.linenos pre {
-    padding: 5px 0px;
-    border: 0;
-    background-color: transparent;
-    color: #aaa;
-}
-
-table.highlighttable {
-    margin-left: 0.5em;
-}
-
-table.highlighttable td {
-    padding: 0 0.5em 0 0.5em;
-}
-
-div.code-block-caption {
-    padding: 2px 5px;
-    font-size: small;
-}
-
-div.code-block-caption code {
-    background-color: transparent;
-}
-
-div.code-block-caption + div > div.highlight > pre {
-    margin-top: 0;
-}
-
-div.code-block-caption span.caption-number {
-    padding: 0.1em 0.3em;
-    font-style: italic;
-}
-
-div.code-block-caption span.caption-text {
-}
-
-div.literal-block-wrapper {
-    padding: 1em 1em 0;
-}
-
-div.literal-block-wrapper div.highlight {
-    margin: 0;
-}
-
-code.descname {
-    background-color: transparent;
-    font-weight: bold;
-    font-size: 1.2em;
-}
-
-code.descclassname {
-    background-color: transparent;
-}
-
-code.xref, a code {
-    background-color: transparent;
-    font-weight: bold;
-}
-
-h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
-    background-color: transparent;
-}
-
-.viewcode-link {
-    float: right;
-}
-
-.viewcode-back {
-    float: right;
-    font-family: sans-serif;
-}
-
-div.viewcode-block:target {
-    margin: -1px -10px;
-    padding: 0 10px;
-}
-
-/* -- math display ---------------------------------------------------------- */
-
-img.math {
-    vertical-align: middle;
-}
-
-div.body div.math p {
-    text-align: center;
-}
-
-span.eqno {
-    float: right;
-}
-
-/* -- printout stylesheet --------------------------------------------------- */
-
-@media print {
-    div.document,
-    div.documentwrapper,
-    div.bodywrapper {
-        margin: 0 !important;
-        width: 100%;
-    }
-
-    div.sphinxsidebar,
-    div.related,
-    div.footer,
-    #top-link {
-        display: none;
-    }
-}
\ No newline at end of file
diff --git a/src/doc/user/sphinx/_build/html/_static/comment-bright.png b/src/doc/user/sphinx/_build/html/_static/comment-bright.png
deleted file mode 100644
index 4a2bf8afad6ba19a9121411b759f1787a95abe9b..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3500
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
ARR910

diff --git a/src/doc/user/sphinx/_build/html/_static/comment.png b/src/doc/user/sphinx/_build/html/_static/comment.png
deleted file mode 100644
index e651e983847ea8017b8c2266f57cb4fdb80cb38e..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3445
zcmV-*4T|!KP)Oz@Z0f2-7z;ux~O9+4z06=<WDR*FRcSTFz-
zW=q650N5=6FiBTtNC2?60Km==3$g$R3;-}uh=nNt1bYBr$Ri_o0EC$U6h`t_Jn<{8
z5a%iY0C<_QJh>z}MS)ugEpZ1|S1ukX&Pf+56gFW3VVXcL!g-k)GJ!M?;PcD?0HBc-
z5#WRK{dmp}uFlRjj{U%*%WZ25jX
z{P*?XzTzZ-GF^d31o+^>%=Ap99M6&ogks$0k4OBs3;+Bb(;~!4V!2o<6ys46agIcq
zjPo+3B8fthDa9qy|77CdEc*jK-!%ZRYCZvbku9iQV*~a}ClFY4z~c7+0P?$U!PF=S
z1Au6Q;m>#f??3%Vpd|o+W=WE9003S@Bra6Svp>fO002awfhw>;8}z{#EWidF!3EsG
z3;bXU&9EIRU@z1_9W=mEXoiz;4lcq~xDGvV5BgyU
zp1~-*fe8db$Osc*A=-!mVv1NJjtCc-h4>-CNCXm#Bp}I%6j35eku^v$Qi@a{RY)E3
zJ#qp$hg?Rwkvqr$GJ^buyhkyVfwECO)C{#lxu`c9ghrwZ&}4KmnvWKso6vH!8a<3Q
zq36)6Xb;+tK10Vaz~~qUGsJ8#F2=(`u{bOVlVi)VBCHIn#u~6ztOL7=^<&SmcLWlF
zMZgI*1b0FpVIDz9SWH+>*hr`#93(Um+6gxa1B6k+CnA%mOSC4s5&6UzVlpv@SV$}*
z))J2sFA#f(L&P^E5{W}HC%KRUNwK6<(h|}}(r!{C=`5+6G)NjFlgZj-YqAG9lq?`C
z$c5yc>d>VnA`E_*3F2Qp##d8RZb=H01_mm@+|Cqnc9PsG(F5HIG_C
zt)aG3uTh7n6Et<2In9F>NlT@zqLtGcXcuVrX|L#Xx)I%#9!{6gSJKPrN9dR61N3(c
z4Tcqi$B1Vr8Jidf7-t!G7_XR2rWwr)$3XQ?}=hpK0&Z&W{|
zep&sA23f;Q!%st`QJ}G3cbou<7-yIK2z4nfCCCtN2-XOGSWo##{8Q{ATurxr~;I`ytDs%xbip}RzP
zziy}Qn4Z2~fSycmr`~zJ=lUFdFa1>gZThG6M+{g7vkW8#+YHVaJjFF}Z#*3@$J_By
zLtVo_L#1JrVVB{Ak-5=4qt!-@Mh}c>#$4kh<88)m#-k<%CLtzEP3leVno>={htGUuD;o7bD)w_sX$S}eAxwzy?UvgBH(S?;#HZiQMoS*2K2
zT3xe7t(~nU*1N5{rxB;QPLocnp4Ml>u<^FZwyC!nu;thW+pe~4wtZn|Vi#w(#jeBd
zlf9FDx_yoPJqHbk*$%56S{;6Kv~mM9!g3B(KJ}#RZ#@)!hR|78Dq|Iq-afF%KE1Brn_fm;Im
z_u$xr8UFki1L{Ox>G0o)(&RAZ;=|I=wN2l97;cLaHH6leTB-XXa*h%dBOEvi`+x
zi?=Txl?TadvyiL>SuF~-LZ;|cS}4~l2eM~nS7yJ>iOM;atDY;(?aZ^v+mJV$@1Ote
z62cPUlD4IWOIIx&SmwQ~YB{nzae3Pc;}r!fhE@iwJh+OsDs9zItL;~pu715HdQEGA
zUct(O!LkCy1<%NCg+}G`0PgpNm-?d@-hMgNe6^V+j6x$b<6@S<$+<4_1hi}Ti
zncS4LsjI}fWY1>OX6feMEuLErma3QLmkw?X+1j)X-&VBk_4Y;EFPF_I+q;9dL%E~B
zJh;4Nr^(LEJ3myURP{Rblsw%57T)g973R8o)DE9*xN#~;4_o$q%o
z4K@u`jhx2fBXC4{U8Qn{*%*B$Ge=nny$HAYq{=vy|sI0
z_vss+H_qMky?OB#|JK!>IX&II^LlUh#rO5!7TtbwC;iULyV-Xq?ybB}ykGP{?LpZ?
z-G|jbTmIbG@7#ZCz;~eY(cDM(28Dyq{*m>M4?_iynUBkc4TkHUI6gT!;y-fz>HMcd
z&t%Ugo)`Y2{>!cx7B7DI)$7;J(U{Spm-3gBzioV_{p!H$8L!*M!p0uH$#^p{Ui4P`
z?ZJ24cOCDe-w#jZd?0@)|7iKK^;6KN`;!@ylm7$*nDhK&GcDTy000JJOGiWi{{a60
z|De66lK=n!32;bRa{vGf6951U69E94oEQKA00(qQO+^Rb3=0S6ce?Lsn$m^3Q`48f|TwQ+_-Qh=t8Ra7nE)y
zf@08(pjZ@22^EVjG*%30TJRMkBUC$WqZ73uoiv&J=APqX;!v%AH}`Vx`999MVjXwy
z{f1-vh8P<=plv&cZ>p5jjX~Vt&W0e)wpw1RFRuRdDkwlKb01tp5
zP=trFN0gH^|L4jJkB{6sCV;Q!ewpg-D&4cza%GQ*b>R*=34#dW;ek`FEiB(vnw+U#
zpOX5UMJBhIN&;D1!yQoIAySC!9zqJmmfoJqmQp}p&h*HTfMh~u9rKic2oz3sNM^#F
zBIq*MRLbsMt%y{EHj8}LeqUUvoxf0=kqji62>ne+U`d#%J)abyK&Y`=eD%oA!36<)baZyK
zXJh5im6umkS|_CSGXips$nI)oBHXojzBzyY_M5K*uvb0_9viuBVyV%5VtJ*Am1ag#
zczbv4B?u8j68iOz<+)nDu^oWnL+$_G{PZOCcOGQ?!1VCefves~rfpaEZs-PdVYMiV
z98ElaJ2}7f;htSXFY#Zv?__sQeckE^HV{ItO=)2hMQs=(_
Xn!ZpXD%P(H00000NkvXXu0mjf%hZK?

diff --git a/src/doc/user/sphinx/_build/html/_static/custom.css b/src/doc/user/sphinx/_build/html/_static/custom.css
deleted file mode 100644
index 2a924f1d..00000000
--- a/src/doc/user/sphinx/_build/html/_static/custom.css
+++ /dev/null
@@ -1 +0,0 @@
-/* This file intentionally left blank. */
diff --git a/src/doc/user/sphinx/_build/html/_static/doctools.js b/src/doc/user/sphinx/_build/html/_static/doctools.js
deleted file mode 100644
index 81634956..00000000
--- a/src/doc/user/sphinx/_build/html/_static/doctools.js
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * doctools.js
- * ~~~~~~~~~~~
- *
- * Sphinx JavaScript utilities for all documentation.
- *
- * :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
- * :license: BSD, see LICENSE for details.
- *
- */
-
-/**
- * select a different prefix for underscore
- */
-$u = _.noConflict();
-
-/**
- * make the code below compatible with browsers without
- * an installed firebug like debugger
-if (!window.console || !console.firebug) {
-  var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
-    "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
-    "profile", "profileEnd"];
-  window.console = {};
-  for (var i = 0; i < names.length; ++i)
-    window.console[names[i]] = function() {};
-}
- */
-
-/**
- * small helper function to urldecode strings
- */
-jQuery.urldecode = function(x) {
-  return decodeURIComponent(x).replace(/\+/g, ' ');
-};
-
-/**
- * small helper function to urlencode strings
- */
-jQuery.urlencode = encodeURIComponent;
-
-/**
- * This function returns the parsed url parameters of the
- * current request. Multiple values per key are supported,
- * it will always return arrays of strings for the value parts.
- */
-jQuery.getQueryParameters = function(s) {
-  if (typeof s == 'undefined')
-    s = document.location.search;
-  var parts = s.substr(s.indexOf('?') + 1).split('&');
-  var result = {};
-  for (var i = 0; i < parts.length; i++) {
-    var tmp = parts[i].split('=', 2);
-    var key = jQuery.urldecode(tmp[0]);
-    var value = jQuery.urldecode(tmp[1]);
-    if (key in result)
-      result[key].push(value);
-    else
-      result[key] = [value];
-  }
-  return result;
-};
-
-/**
- * highlight a given string on a jquery object by wrapping it in
- * span elements with the given class name.
- */
-jQuery.fn.highlightText = function(text, className) {
-  function highlight(node) {
-    if (node.nodeType == 3) {
-      var val = node.nodeValue;
-      var pos = val.toLowerCase().indexOf(text);
-      if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) {
-        var span = document.createElement("span");
-        span.className = className;
-        span.appendChild(document.createTextNode(val.substr(pos, text.length)));
-        node.parentNode.insertBefore(span, node.parentNode.insertBefore(
-          document.createTextNode(val.substr(pos + text.length)),
-          node.nextSibling));
-        node.nodeValue = val.substr(0, pos);
-      }
-    }
-    else if (!jQuery(node).is("button, select, textarea")) {
-      jQuery.each(node.childNodes, function() {
-        highlight(this);
-      });
-    }
-  }
-  return this.each(function() {
-    highlight(this);
-  });
-};
-
-/*
- * backward compatibility for jQuery.browser
- * This will be supported until firefox bug is fixed.
- */
-if (!jQuery.browser) {
-  jQuery.uaMatch = function(ua) {
-    ua = ua.toLowerCase();
-
-    var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
-      /(webkit)[ \/]([\w.]+)/.exec(ua) ||
-      /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
-      /(msie) ([\w.]+)/.exec(ua) ||
-      ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
-      [];
-
-    return {
-      browser: match[ 1 ] || "",
-      version: match[ 2 ] || "0"
-    };
-  };
-  jQuery.browser = {};
-  jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
-}
-
-/**
- * Small JavaScript module for the documentation.
- */
-var Documentation = {
-
-  init : function() {
-    this.fixFirefoxAnchorBug();
-    this.highlightSearchWords();
-    this.initIndexTable();
-    
-  },
-
-  /**
-   * i18n support
-   */
-  TRANSLATIONS : {},
-  PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },
-  LOCALE : 'unknown',
-
-  // gettext and ngettext don't access this so that the functions
-  // can safely bound to a different name (_ = Documentation.gettext)
-  gettext : function(string) {
-    var translated = Documentation.TRANSLATIONS[string];
-    if (typeof translated == 'undefined')
-      return string;
-    return (typeof translated == 'string') ? translated : translated[0];
-  },
-
-  ngettext : function(singular, plural, n) {
-    var translated = Documentation.TRANSLATIONS[singular];
-    if (typeof translated == 'undefined')
-      return (n == 1) ? singular : plural;
-    return translated[Documentation.PLURALEXPR(n)];
-  },
-
-  addTranslations : function(catalog) {
-    for (var key in catalog.messages)
-      this.TRANSLATIONS[key] = catalog.messages[key];
-    this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
-    this.LOCALE = catalog.locale;
-  },
-
-  /**
-   * add context elements like header anchor links
-   */
-  addContextElements : function() {
-    $('div[id] > :header:first').each(function() {
-      $('\u00B6').
-      attr('href', '#' + this.id).
-      attr('title', _('Permalink to this headline')).
-      appendTo(this);
-    });
-    $('dt[id]').each(function() {
-      $('\u00B6').
-      attr('href', '#' + this.id).
-      attr('title', _('Permalink to this definition')).
-      appendTo(this);
-    });
-  },
-
-  /**
-   * workaround a firefox stupidity
-   * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075
-   */
-  fixFirefoxAnchorBug : function() {
-    if (document.location.hash)
-      window.setTimeout(function() {
-        document.location.href += '';
-      }, 10);
-  },
-
-  /**
-   * highlight the search words provided in the url in the text
-   */
-  highlightSearchWords : function() {
-    var params = $.getQueryParameters();
-    var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
-    if (terms.length) {
-      var body = $('div.body');
-      if (!body.length) {
-        body = $('body');
-      }
-      window.setTimeout(function() {
-        $.each(terms, function() {
-          body.highlightText(this.toLowerCase(), 'highlighted');
-        });
-      }, 10);
-      $('')
-          .appendTo($('#searchbox'));
-    }
-  },
-
-  /**
-   * init the domain index toggle buttons
-   */
-  initIndexTable : function() {
-    var togglers = $('img.toggler').click(function() {
-      var src = $(this).attr('src');
-      var idnum = $(this).attr('id').substr(7);
-      $('tr.cg-' + idnum).toggle();
-      if (src.substr(-9) == 'minus.png')
-        $(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
-      else
-        $(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
-    }).css('display', '');
-    if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
-        togglers.click();
-    }
-  },
-
-  /**
-   * helper function to hide the search marks again
-   */
-  hideSearchWords : function() {
-    $('#searchbox .highlight-link').fadeOut(300);
-    $('span.highlighted').removeClass('highlighted');
-  },
-
-  /**
-   * make the url absolute
-   */
-  makeURL : function(relativeURL) {
-    return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
-  },
-
-  /**
-   * get the current relative url
-   */
-  getCurrentURL : function() {
-    var path = document.location.pathname;
-    var parts = path.split(/\//);
-    $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
-      if (this == '..')
-        parts.pop();
-    });
-    var url = parts.join('/');
-    return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
-  },
-
-  initOnKeyListeners: function() {
-    $(document).keyup(function(event) {
-      var activeElementType = document.activeElement.tagName;
-      // don't navigate when in search box or textarea
-      if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') {
-        switch (event.keyCode) {
-          case 37: // left
-            var prevHref = $('link[rel="prev"]').prop('href');
-            if (prevHref) {
-              window.location.href = prevHref;
-              return false;
-            }
-          case 39: // right
-            var nextHref = $('link[rel="next"]').prop('href');
-            if (nextHref) {
-              window.location.href = nextHref;
-              return false;
-            }
-        }
-      }
-    });
-  }
-};
-
-// quick alias for translations
-_ = Documentation.gettext;
-
-$(document).ready(function() {
-  Documentation.init();
-});
\ No newline at end of file
diff --git a/src/doc/user/sphinx/_build/html/_static/down-pressed.png b/src/doc/user/sphinx/_build/html/_static/down-pressed.png
deleted file mode 100644
index 20cd4e2ba13419352a7ee86096499852b28b904e..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 347
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~&H|6fVxZ#d
zAk65bF}ngN$X?><>&pIshnqu7n|0~_Pe38R0G|+7AiX(0o?3|Y%0qjgiIOEje!&dP
zEIfirrnW9I@rh+CRvx(W^3}&LzkdJucj$HfU!Wq!ByV>Yh7ML)4+Owih~6_U7{H+20PQ*-6b*
z3U+={`mtu`S&29dFAtFjffxGew#NxNSnYW^xA9HDi6!!!TG<>&pIshnqu7n|0~_Pe38R0G|+7Abpg2VER$pJfMk^B|(0{49qM%
zf=Z^gE-~?mWh+)5xbpJV$1lHr|M_?5b^TwUBE}?dcNc~ZR#^`qC(+ZzF+@VL_h6)0
zlYxlKLGKw870;~yzCSSeiN?>xT|F*tk;TE&4St!apNh5@I#c%M^6J^&4yV~k%~T3@
zep33eX6IRv8_#xpF*FVdQ&MBb@07+b#g8%>k

diff --git a/src/doc/user/sphinx/_build/html/_static/file.png b/src/doc/user/sphinx/_build/html/_static/file.png
deleted file mode 100644
index eedc81941066e54aa42a4548507fe527f9f47e56..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 358
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJXMsm#F#`j)FbFd;%$g$s6l5>)
z^mS!_z{Aadculfn-K;OJ+%1Ze@RN)ug;?Aevk>
z|2$AZThElvDT_L1tnHk+u4~r%Svzj5ICSQ~l_NlK^ytxJ$BrF8e*D#|SFc~ce)Hzd
z+qX~O0>Q^?@7}$8|Ni}l4<9~${P^k9r~m)|Gpnp!4z!ZBB*-tAA#BB(Ev7f_r2_>R
zlf2zsRJO4FoC)OQc)B=-NJz3Cbo4tEz`%N-azB60;d87X|1B@>z9=;5)_I?4ybSfh
z+w~c0{%f5N?zqVM)JDl;;SP?&465!9W*Sn5=dd1SE@&5eooip&cs!gPwA!6TgEjXE$87Os@YS}87N0koIF)78&qol`;+0IgM*(EtDd

diff --git a/src/doc/user/sphinx/_build/html/_static/jquery.js b/src/doc/user/sphinx/_build/html/_static/jquery.js
deleted file mode 100644
index 25a72c95..00000000
--- a/src/doc/user/sphinx/_build/html/_static/jquery.js
+++ /dev/null
@@ -1,10219 +0,0 @@
-/*!
- * jQuery JavaScript Library v3.1.1
- * https://jquery.com/
- *
- * Includes Sizzle.js
- * https://sizzlejs.com/
- *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license
- * https://jquery.org/license
- *
- * Date: 2016-12-11T15:18Z
- */
-( function( global, factory ) {
-
-	"use strict";
-
-	if ( typeof module === "object" && typeof module.exports === "object" ) {
-
-		// For CommonJS and CommonJS-like environments where a proper `window`
-		// is present, execute the factory and get jQuery.
-		// For environments that do not have a `window` with a `document`
-		// (such as Node.js), expose a factory as module.exports.
-		// This accentuates the need for the creation of a real `window`.
-		// e.g. var jQuery = require("jquery")(window);
-		// See ticket #14549 for more info.
-		module.exports = global.document ?
-			factory( global, true ) :
-			function( w ) {
-				if ( !w.document ) {
-					throw new Error( "jQuery requires a window with a document" );
-				}
-				return factory( w );
-			};
-	} else {
-		factory( global );
-	}
-
-// Pass this if window is not defined yet
-} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
-
-// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
-// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
-// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
-// enough that all such attempts are guarded in a try block.
-
-
-var arr = [];
-
-var document = window.document;
-
-var getProto = Object.getPrototypeOf;
-
-var slice = arr.slice;
-
-var concat = arr.concat;
-
-var push = arr.push;
-
-var indexOf = arr.indexOf;
-
-var class2type = {};
-
-var toString = class2type.toString;
-
-var hasOwn = class2type.hasOwnProperty;
-
-var fnToString = hasOwn.toString;
-
-var ObjectFunctionString = fnToString.call( Object );
-
-var support = {};
-
-
-
-	function DOMEval( code, doc ) {
-		doc = doc || document;
-
-		var script = doc.createElement( "script" );
-
-		script.text = code;
-		doc.head.appendChild( script ).parentNode.removeChild( script );
-	}
-/* global Symbol */
-// Defining this global in .eslintrc.json would create a danger of using the global
-// unguarded in another place, it seems safer to define global only for this module
-
-
-
-var
-	version = "3.1.1",
-
-	// Define a local copy of jQuery
-	jQuery = function( selector, context ) {
-
-		// The jQuery object is actually just the init constructor 'enhanced'
-		// Need init if jQuery is called (just allow error to be thrown if not included)
-		return new jQuery.fn.init( selector, context );
-	},
-
-	// Support: Android <=4.0 only
-	// Make sure we trim BOM and NBSP
-	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
-
-	// Matches dashed string for camelizing
-	rmsPrefix = /^-ms-/,
-	rdashAlpha = /-([a-z])/g,
-
-	// Used by jQuery.camelCase as callback to replace()
-	fcamelCase = function( all, letter ) {
-		return letter.toUpperCase();
-	};
-
-jQuery.fn = jQuery.prototype = {
-
-	// The current version of jQuery being used
-	jquery: version,
-
-	constructor: jQuery,
-
-	// The default length of a jQuery object is 0
-	length: 0,
-
-	toArray: function() {
-		return slice.call( this );
-	},
-
-	// Get the Nth element in the matched element set OR
-	// Get the whole matched element set as a clean array
-	get: function( num ) {
-
-		// Return all the elements in a clean array
-		if ( num == null ) {
-			return slice.call( this );
-		}
-
-		// Return just the one element from the set
-		return num < 0 ? this[ num + this.length ] : this[ num ];
-	},
-
-	// Take an array of elements and push it onto the stack
-	// (returning the new matched element set)
-	pushStack: function( elems ) {
-
-		// Build a new jQuery matched element set
-		var ret = jQuery.merge( this.constructor(), elems );
-
-		// Add the old object onto the stack (as a reference)
-		ret.prevObject = this;
-
-		// Return the newly-formed element set
-		return ret;
-	},
-
-	// Execute a callback for every element in the matched set.
-	each: function( callback ) {
-		return jQuery.each( this, callback );
-	},
-
-	map: function( callback ) {
-		return this.pushStack( jQuery.map( this, function( elem, i ) {
-			return callback.call( elem, i, elem );
-		} ) );
-	},
-
-	slice: function() {
-		return this.pushStack( slice.apply( this, arguments ) );
-	},
-
-	first: function() {
-		return this.eq( 0 );
-	},
-
-	last: function() {
-		return this.eq( -1 );
-	},
-
-	eq: function( i ) {
-		var len = this.length,
-			j = +i + ( i < 0 ? len : 0 );
-		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
-	},
-
-	end: function() {
-		return this.prevObject || this.constructor();
-	},
-
-	// For internal use only.
-	// Behaves like an Array's method, not like a jQuery method.
-	push: push,
-	sort: arr.sort,
-	splice: arr.splice
-};
-
-jQuery.extend = jQuery.fn.extend = function() {
-	var options, name, src, copy, copyIsArray, clone,
-		target = arguments[ 0 ] || {},
-		i = 1,
-		length = arguments.length,
-		deep = false;
-
-	// Handle a deep copy situation
-	if ( typeof target === "boolean" ) {
-		deep = target;
-
-		// Skip the boolean and the target
-		target = arguments[ i ] || {};
-		i++;
-	}
-
-	// Handle case when target is a string or something (possible in deep copy)
-	if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
-		target = {};
-	}
-
-	// Extend jQuery itself if only one argument is passed
-	if ( i === length ) {
-		target = this;
-		i--;
-	}
-
-	for ( ; i < length; i++ ) {
-
-		// Only deal with non-null/undefined values
-		if ( ( options = arguments[ i ] ) != null ) {
-
-			// Extend the base object
-			for ( name in options ) {
-				src = target[ name ];
-				copy = options[ name ];
-
-				// Prevent never-ending loop
-				if ( target === copy ) {
-					continue;
-				}
-
-				// Recurse if we're merging plain objects or arrays
-				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
-					( copyIsArray = jQuery.isArray( copy ) ) ) ) {
-
-					if ( copyIsArray ) {
-						copyIsArray = false;
-						clone = src && jQuery.isArray( src ) ? src : [];
-
-					} else {
-						clone = src && jQuery.isPlainObject( src ) ? src : {};
-					}
-
-					// Never move original objects, clone them
-					target[ name ] = jQuery.extend( deep, clone, copy );
-
-				// Don't bring in undefined values
-				} else if ( copy !== undefined ) {
-					target[ name ] = copy;
-				}
-			}
-		}
-	}
-
-	// Return the modified object
-	return target;
-};
-
-jQuery.extend( {
-
-	// Unique for each copy of jQuery on the page
-	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
-
-	// Assume jQuery is ready without the ready module
-	isReady: true,
-
-	error: function( msg ) {
-		throw new Error( msg );
-	},
-
-	noop: function() {},
-
-	isFunction: function( obj ) {
-		return jQuery.type( obj ) === "function";
-	},
-
-	isArray: Array.isArray,
-
-	isWindow: function( obj ) {
-		return obj != null && obj === obj.window;
-	},
-
-	isNumeric: function( obj ) {
-
-		// As of jQuery 3.0, isNumeric is limited to
-		// strings and numbers (primitives or objects)
-		// that can be coerced to finite numbers (gh-2662)
-		var type = jQuery.type( obj );
-		return ( type === "number" || type === "string" ) &&
-
-			// parseFloat NaNs numeric-cast false positives ("")
-			// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
-			// subtraction forces infinities to NaN
-			!isNaN( obj - parseFloat( obj ) );
-	},
-
-	isPlainObject: function( obj ) {
-		var proto, Ctor;
-
-		// Detect obvious negatives
-		// Use toString instead of jQuery.type to catch host objects
-		if ( !obj || toString.call( obj ) !== "[object Object]" ) {
-			return false;
-		}
-
-		proto = getProto( obj );
-
-		// Objects with no prototype (e.g., `Object.create( null )`) are plain
-		if ( !proto ) {
-			return true;
-		}
-
-		// Objects with prototype are plain iff they were constructed by a global Object function
-		Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
-		return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
-	},
-
-	isEmptyObject: function( obj ) {
-
-		/* eslint-disable no-unused-vars */
-		// See https://github.com/eslint/eslint/issues/6125
-		var name;
-
-		for ( name in obj ) {
-			return false;
-		}
-		return true;
-	},
-
-	type: function( obj ) {
-		if ( obj == null ) {
-			return obj + "";
-		}
-
-		// Support: Android <=2.3 only (functionish RegExp)
-		return typeof obj === "object" || typeof obj === "function" ?
-			class2type[ toString.call( obj ) ] || "object" :
-			typeof obj;
-	},
-
-	// Evaluates a script in a global context
-	globalEval: function( code ) {
-		DOMEval( code );
-	},
-
-	// Convert dashed to camelCase; used by the css and data modules
-	// Support: IE <=9 - 11, Edge 12 - 13
-	// Microsoft forgot to hump their vendor prefix (#9572)
-	camelCase: function( string ) {
-		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
-	},
-
-	nodeName: function( elem, name ) {
-		return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
-	},
-
-	each: function( obj, callback ) {
-		var length, i = 0;
-
-		if ( isArrayLike( obj ) ) {
-			length = obj.length;
-			for ( ; i < length; i++ ) {
-				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
-					break;
-				}
-			}
-		} else {
-			for ( i in obj ) {
-				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
-					break;
-				}
-			}
-		}
-
-		return obj;
-	},
-
-	// Support: Android <=4.0 only
-	trim: function( text ) {
-		return text == null ?
-			"" :
-			( text + "" ).replace( rtrim, "" );
-	},
-
-	// results is for internal usage only
-	makeArray: function( arr, results ) {
-		var ret = results || [];
-
-		if ( arr != null ) {
-			if ( isArrayLike( Object( arr ) ) ) {
-				jQuery.merge( ret,
-					typeof arr === "string" ?
-					[ arr ] : arr
-				);
-			} else {
-				push.call( ret, arr );
-			}
-		}
-
-		return ret;
-	},
-
-	inArray: function( elem, arr, i ) {
-		return arr == null ? -1 : indexOf.call( arr, elem, i );
-	},
-
-	// Support: Android <=4.0 only, PhantomJS 1 only
-	// push.apply(_, arraylike) throws on ancient WebKit
-	merge: function( first, second ) {
-		var len = +second.length,
-			j = 0,
-			i = first.length;
-
-		for ( ; j < len; j++ ) {
-			first[ i++ ] = second[ j ];
-		}
-
-		first.length = i;
-
-		return first;
-	},
-
-	grep: function( elems, callback, invert ) {
-		var callbackInverse,
-			matches = [],
-			i = 0,
-			length = elems.length,
-			callbackExpect = !invert;
-
-		// Go through the array, only saving the items
-		// that pass the validator function
-		for ( ; i < length; i++ ) {
-			callbackInverse = !callback( elems[ i ], i );
-			if ( callbackInverse !== callbackExpect ) {
-				matches.push( elems[ i ] );
-			}
-		}
-
-		return matches;
-	},
-
-	// arg is for internal usage only
-	map: function( elems, callback, arg ) {
-		var length, value,
-			i = 0,
-			ret = [];
-
-		// Go through the array, translating each of the items to their new values
-		if ( isArrayLike( elems ) ) {
-			length = elems.length;
-			for ( ; i < length; i++ ) {
-				value = callback( elems[ i ], i, arg );
-
-				if ( value != null ) {
-					ret.push( value );
-				}
-			}
-
-		// Go through every key on the object,
-		} else {
-			for ( i in elems ) {
-				value = callback( elems[ i ], i, arg );
-
-				if ( value != null ) {
-					ret.push( value );
-				}
-			}
-		}
-
-		// Flatten any nested arrays
-		return concat.apply( [], ret );
-	},
-
-	// A global GUID counter for objects
-	guid: 1,
-
-	// Bind a function to a context, optionally partially applying any
-	// arguments.
-	proxy: function( fn, context ) {
-		var tmp, args, proxy;
-
-		if ( typeof context === "string" ) {
-			tmp = fn[ context ];
-			context = fn;
-			fn = tmp;
-		}
-
-		// Quick check to determine if target is callable, in the spec
-		// this throws a TypeError, but we will just return undefined.
-		if ( !jQuery.isFunction( fn ) ) {
-			return undefined;
-		}
-
-		// Simulated bind
-		args = slice.call( arguments, 2 );
-		proxy = function() {
-			return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
-		};
-
-		// Set the guid of unique handler to the same of original handler, so it can be removed
-		proxy.guid = fn.guid = fn.guid || jQuery.guid++;
-
-		return proxy;
-	},
-
-	now: Date.now,
-
-	// jQuery.support is not used in Core but other projects attach their
-	// properties to it so it needs to exist.
-	support: support
-} );
-
-if ( typeof Symbol === "function" ) {
-	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
-}
-
-// Populate the class2type map
-jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
-function( i, name ) {
-	class2type[ "[object " + name + "]" ] = name.toLowerCase();
-} );
-
-function isArrayLike( obj ) {
-
-	// Support: real iOS 8.2 only (not reproducible in simulator)
-	// `in` check used to prevent JIT error (gh-2145)
-	// hasOwn isn't used here due to false negatives
-	// regarding Nodelist length in IE
-	var length = !!obj && "length" in obj && obj.length,
-		type = jQuery.type( obj );
-
-	if ( type === "function" || jQuery.isWindow( obj ) ) {
-		return false;
-	}
-
-	return type === "array" || length === 0 ||
-		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
-}
-var Sizzle =
-/*!
- * Sizzle CSS Selector Engine v2.3.3
- * https://sizzlejs.com/
- *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license
- * http://jquery.org/license
- *
- * Date: 2016-08-08
- */
-(function( window ) {
-
-var i,
-	support,
-	Expr,
-	getText,
-	isXML,
-	tokenize,
-	compile,
-	select,
-	outermostContext,
-	sortInput,
-	hasDuplicate,
-
-	// Local document vars
-	setDocument,
-	document,
-	docElem,
-	documentIsHTML,
-	rbuggyQSA,
-	rbuggyMatches,
-	matches,
-	contains,
-
-	// Instance-specific data
-	expando = "sizzle" + 1 * new Date(),
-	preferredDoc = window.document,
-	dirruns = 0,
-	done = 0,
-	classCache = createCache(),
-	tokenCache = createCache(),
-	compilerCache = createCache(),
-	sortOrder = function( a, b ) {
-		if ( a === b ) {
-			hasDuplicate = true;
-		}
-		return 0;
-	},
-
-	// Instance methods
-	hasOwn = ({}).hasOwnProperty,
-	arr = [],
-	pop = arr.pop,
-	push_native = arr.push,
-	push = arr.push,
-	slice = arr.slice,
-	// Use a stripped-down indexOf as it's faster than native
-	// https://jsperf.com/thor-indexof-vs-for/5
-	indexOf = function( list, elem ) {
-		var i = 0,
-			len = list.length;
-		for ( ; i < len; i++ ) {
-			if ( list[i] === elem ) {
-				return i;
-			}
-		}
-		return -1;
-	},
-
-	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
-
-	// Regular expressions
-
-	// http://www.w3.org/TR/css3-selectors/#whitespace
-	whitespace = "[\\x20\\t\\r\\n\\f]",
-
-	// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
-	identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",
-
-	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
-	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
-		// Operator (capture 2)
-		"*([*^$|!~]?=)" + whitespace +
-		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
-		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
-		"*\\]",
-
-	pseudos = ":(" + identifier + ")(?:\\((" +
-		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
-		// 1. quoted (capture 3; capture 4 or capture 5)
-		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
-		// 2. simple (capture 6)
-		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
-		// 3. anything else (capture 2)
-		".*" +
-		")\\)|)",
-
-	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
-	rwhitespace = new RegExp( whitespace + "+", "g" ),
-	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
-
-	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
-	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
-
-	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
-
-	rpseudo = new RegExp( pseudos ),
-	ridentifier = new RegExp( "^" + identifier + "$" ),
-
-	matchExpr = {
-		"ID": new RegExp( "^#(" + identifier + ")" ),
-		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
-		"TAG": new RegExp( "^(" + identifier + "|[*])" ),
-		"ATTR": new RegExp( "^" + attributes ),
-		"PSEUDO": new RegExp( "^" + pseudos ),
-		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
-			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
-			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
-		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
-		// For use in libraries implementing .is()
-		// We use this for POS matching in `select`
-		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
-			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
-	},
-
-	rinputs = /^(?:input|select|textarea|button)$/i,
-	rheader = /^h\d$/i,
-
-	rnative = /^[^{]+\{\s*\[native \w/,
-
-	// Easily-parseable/retrievable ID or TAG or CLASS selectors
-	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
-
-	rsibling = /[+~]/,
-
-	// CSS escapes
-	// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
-	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
-	funescape = function( _, escaped, escapedWhitespace ) {
-		var high = "0x" + escaped - 0x10000;
-		// NaN means non-codepoint
-		// Support: Firefox<24
-		// Workaround erroneous numeric interpretation of +"0x"
-		return high !== high || escapedWhitespace ?
-			escaped :
-			high < 0 ?
-				// BMP codepoint
-				String.fromCharCode( high + 0x10000 ) :
-				// Supplemental Plane codepoint (surrogate pair)
-				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
-	},
-
-	// CSS string/identifier serialization
-	// https://drafts.csswg.org/cssom/#common-serializing-idioms
-	rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
-	fcssescape = function( ch, asCodePoint ) {
-		if ( asCodePoint ) {
-
-			// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
-			if ( ch === "\0" ) {
-				return "\uFFFD";
-			}
-
-			// Control characters and (dependent upon position) numbers get escaped as code points
-			return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
-		}
-
-		// Other potentially-special ASCII characters get backslash-escaped
-		return "\\" + ch;
-	},
-
-	// Used for iframes
-	// See setDocument()
-	// Removing the function wrapper causes a "Permission Denied"
-	// error in IE
-	unloadHandler = function() {
-		setDocument();
-	},
-
-	disabledAncestor = addCombinator(
-		function( elem ) {
-			return elem.disabled === true && ("form" in elem || "label" in elem);
-		},
-		{ dir: "parentNode", next: "legend" }
-	);
-
-// Optimize for push.apply( _, NodeList )
-try {
-	push.apply(
-		(arr = slice.call( preferredDoc.childNodes )),
-		preferredDoc.childNodes
-	);
-	// Support: Android<4.0
-	// Detect silently failing push.apply
-	arr[ preferredDoc.childNodes.length ].nodeType;
-} catch ( e ) {
-	push = { apply: arr.length ?
-
-		// Leverage slice if possible
-		function( target, els ) {
-			push_native.apply( target, slice.call(els) );
-		} :
-
-		// Support: IE<9
-		// Otherwise append directly
-		function( target, els ) {
-			var j = target.length,
-				i = 0;
-			// Can't trust NodeList.length
-			while ( (target[j++] = els[i++]) ) {}
-			target.length = j - 1;
-		}
-	};
-}
-
-function Sizzle( selector, context, results, seed ) {
-	var m, i, elem, nid, match, groups, newSelector,
-		newContext = context && context.ownerDocument,
-
-		// nodeType defaults to 9, since context defaults to document
-		nodeType = context ? context.nodeType : 9;
-
-	results = results || [];
-
-	// Return early from calls with invalid selector or context
-	if ( typeof selector !== "string" || !selector ||
-		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
-
-		return results;
-	}
-
-	// Try to shortcut find operations (as opposed to filters) in HTML documents
-	if ( !seed ) {
-
-		if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
-			setDocument( context );
-		}
-		context = context || document;
-
-		if ( documentIsHTML ) {
-
-			// If the selector is sufficiently simple, try using a "get*By*" DOM method
-			// (excepting DocumentFragment context, where the methods don't exist)
-			if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
-
-				// ID selector
-				if ( (m = match[1]) ) {
-
-					// Document context
-					if ( nodeType === 9 ) {
-						if ( (elem = context.getElementById( m )) ) {
-
-							// Support: IE, Opera, Webkit
-							// TODO: identify versions
-							// getElementById can match elements by name instead of ID
-							if ( elem.id === m ) {
-								results.push( elem );
-								return results;
-							}
-						} else {
-							return results;
-						}
-
-					// Element context
-					} else {
-
-						// Support: IE, Opera, Webkit
-						// TODO: identify versions
-						// getElementById can match elements by name instead of ID
-						if ( newContext && (elem = newContext.getElementById( m )) &&
-							contains( context, elem ) &&
-							elem.id === m ) {
-
-							results.push( elem );
-							return results;
-						}
-					}
-
-				// Type selector
-				} else if ( match[2] ) {
-					push.apply( results, context.getElementsByTagName( selector ) );
-					return results;
-
-				// Class selector
-				} else if ( (m = match[3]) && support.getElementsByClassName &&
-					context.getElementsByClassName ) {
-
-					push.apply( results, context.getElementsByClassName( m ) );
-					return results;
-				}
-			}
-
-			// Take advantage of querySelectorAll
-			if ( support.qsa &&
-				!compilerCache[ selector + " " ] &&
-				(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
-
-				if ( nodeType !== 1 ) {
-					newContext = context;
-					newSelector = selector;
-
-				// qSA looks outside Element context, which is not what we want
-				// Thanks to Andrew Dupont for this workaround technique
-				// Support: IE <=8
-				// Exclude object elements
-				} else if ( context.nodeName.toLowerCase() !== "object" ) {
-
-					// Capture the context ID, setting it first if necessary
-					if ( (nid = context.getAttribute( "id" )) ) {
-						nid = nid.replace( rcssescape, fcssescape );
-					} else {
-						context.setAttribute( "id", (nid = expando) );
-					}
-
-					// Prefix every selector in the list
-					groups = tokenize( selector );
-					i = groups.length;
-					while ( i-- ) {
-						groups[i] = "#" + nid + " " + toSelector( groups[i] );
-					}
-					newSelector = groups.join( "," );
-
-					// Expand context for sibling selectors
-					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
-						context;
-				}
-
-				if ( newSelector ) {
-					try {
-						push.apply( results,
-							newContext.querySelectorAll( newSelector )
-						);
-						return results;
-					} catch ( qsaError ) {
-					} finally {
-						if ( nid === expando ) {
-							context.removeAttribute( "id" );
-						}
-					}
-				}
-			}
-		}
-	}
-
-	// All others
-	return select( selector.replace( rtrim, "$1" ), context, results, seed );
-}
-
-/**
- * Create key-value caches of limited size
- * @returns {function(string, object)} Returns the Object data after storing it on itself with
- *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
- *	deleting the oldest entry
- */
-function createCache() {
-	var keys = [];
-
-	function cache( key, value ) {
-		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
-		if ( keys.push( key + " " ) > Expr.cacheLength ) {
-			// Only keep the most recent entries
-			delete cache[ keys.shift() ];
-		}
-		return (cache[ key + " " ] = value);
-	}
-	return cache;
-}
-
-/**
- * Mark a function for special use by Sizzle
- * @param {Function} fn The function to mark
- */
-function markFunction( fn ) {
-	fn[ expando ] = true;
-	return fn;
-}
-
-/**
- * Support testing using an element
- * @param {Function} fn Passed the created element and returns a boolean result
- */
-function assert( fn ) {
-	var el = document.createElement("fieldset");
-
-	try {
-		return !!fn( el );
-	} catch (e) {
-		return false;
-	} finally {
-		// Remove from its parent by default
-		if ( el.parentNode ) {
-			el.parentNode.removeChild( el );
-		}
-		// release memory in IE
-		el = null;
-	}
-}
-
-/**
- * Adds the same handler for all of the specified attrs
- * @param {String} attrs Pipe-separated list of attributes
- * @param {Function} handler The method that will be applied
- */
-function addHandle( attrs, handler ) {
-	var arr = attrs.split("|"),
-		i = arr.length;
-
-	while ( i-- ) {
-		Expr.attrHandle[ arr[i] ] = handler;
-	}
-}
-
-/**
- * Checks document order of two siblings
- * @param {Element} a
- * @param {Element} b
- * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
- */
-function siblingCheck( a, b ) {
-	var cur = b && a,
-		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
-			a.sourceIndex - b.sourceIndex;
-
-	// Use IE sourceIndex if available on both nodes
-	if ( diff ) {
-		return diff;
-	}
-
-	// Check if b follows a
-	if ( cur ) {
-		while ( (cur = cur.nextSibling) ) {
-			if ( cur === b ) {
-				return -1;
-			}
-		}
-	}
-
-	return a ? 1 : -1;
-}
-
-/**
- * Returns a function to use in pseudos for input types
- * @param {String} type
- */
-function createInputPseudo( type ) {
-	return function( elem ) {
-		var name = elem.nodeName.toLowerCase();
-		return name === "input" && elem.type === type;
-	};
-}
-
-/**
- * Returns a function to use in pseudos for buttons
- * @param {String} type
- */
-function createButtonPseudo( type ) {
-	return function( elem ) {
-		var name = elem.nodeName.toLowerCase();
-		return (name === "input" || name === "button") && elem.type === type;
-	};
-}
-
-/**
- * Returns a function to use in pseudos for :enabled/:disabled
- * @param {Boolean} disabled true for :disabled; false for :enabled
- */
-function createDisabledPseudo( disabled ) {
-
-	// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
-	return function( elem ) {
-
-		// Only certain elements can match :enabled or :disabled
-		// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
-		// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
-		if ( "form" in elem ) {
-
-			// Check for inherited disabledness on relevant non-disabled elements:
-			// * listed form-associated elements in a disabled fieldset
-			//   https://html.spec.whatwg.org/multipage/forms.html#category-listed
-			//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
-			// * option elements in a disabled optgroup
-			//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
-			// All such elements have a "form" property.
-			if ( elem.parentNode && elem.disabled === false ) {
-
-				// Option elements defer to a parent optgroup if present
-				if ( "label" in elem ) {
-					if ( "label" in elem.parentNode ) {
-						return elem.parentNode.disabled === disabled;
-					} else {
-						return elem.disabled === disabled;
-					}
-				}
-
-				// Support: IE 6 - 11
-				// Use the isDisabled shortcut property to check for disabled fieldset ancestors
-				return elem.isDisabled === disabled ||
-
-					// Where there is no isDisabled, check manually
-					/* jshint -W018 */
-					elem.isDisabled !== !disabled &&
-						disabledAncestor( elem ) === disabled;
-			}
-
-			return elem.disabled === disabled;
-
-		// Try to winnow out elements that can't be disabled before trusting the disabled property.
-		// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
-		// even exist on them, let alone have a boolean value.
-		} else if ( "label" in elem ) {
-			return elem.disabled === disabled;
-		}
-
-		// Remaining elements are neither :enabled nor :disabled
-		return false;
-	};
-}
-
-/**
- * Returns a function to use in pseudos for positionals
- * @param {Function} fn
- */
-function createPositionalPseudo( fn ) {
-	return markFunction(function( argument ) {
-		argument = +argument;
-		return markFunction(function( seed, matches ) {
-			var j,
-				matchIndexes = fn( [], seed.length, argument ),
-				i = matchIndexes.length;
-
-			// Match elements found at the specified indexes
-			while ( i-- ) {
-				if ( seed[ (j = matchIndexes[i]) ] ) {
-					seed[j] = !(matches[j] = seed[j]);
-				}
-			}
-		});
-	});
-}
-
-/**
- * Checks a node for validity as a Sizzle context
- * @param {Element|Object=} context
- * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
- */
-function testContext( context ) {
-	return context && typeof context.getElementsByTagName !== "undefined" && context;
-}
-
-// Expose support vars for convenience
-support = Sizzle.support = {};
-
-/**
- * Detects XML nodes
- * @param {Element|Object} elem An element or a document
- * @returns {Boolean} True iff elem is a non-HTML XML node
- */
-isXML = Sizzle.isXML = function( elem ) {
-	// documentElement is verified for cases where it doesn't yet exist
-	// (such as loading iframes in IE - #4833)
-	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
-	return documentElement ? documentElement.nodeName !== "HTML" : false;
-};
-
-/**
- * Sets document-related variables once based on the current document
- * @param {Element|Object} [doc] An element or document object to use to set the document
- * @returns {Object} Returns the current document
- */
-setDocument = Sizzle.setDocument = function( node ) {
-	var hasCompare, subWindow,
-		doc = node ? node.ownerDocument || node : preferredDoc;
-
-	// Return early if doc is invalid or already selected
-	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
-		return document;
-	}
-
-	// Update global variables
-	document = doc;
-	docElem = document.documentElement;
-	documentIsHTML = !isXML( document );
-
-	// Support: IE 9-11, Edge
-	// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
-	if ( preferredDoc !== document &&
-		(subWindow = document.defaultView) && subWindow.top !== subWindow ) {
-
-		// Support: IE 11, Edge
-		if ( subWindow.addEventListener ) {
-			subWindow.addEventListener( "unload", unloadHandler, false );
-
-		// Support: IE 9 - 10 only
-		} else if ( subWindow.attachEvent ) {
-			subWindow.attachEvent( "onunload", unloadHandler );
-		}
-	}
-
-	/* Attributes
-	---------------------------------------------------------------------- */
-
-	// Support: IE<8
-	// Verify that getAttribute really returns attributes and not properties
-	// (excepting IE8 booleans)
-	support.attributes = assert(function( el ) {
-		el.className = "i";
-		return !el.getAttribute("className");
-	});
-
-	/* getElement(s)By*
-	---------------------------------------------------------------------- */
-
-	// Check if getElementsByTagName("*") returns only elements
-	support.getElementsByTagName = assert(function( el ) {
-		el.appendChild( document.createComment("") );
-		return !el.getElementsByTagName("*").length;
-	});
-
-	// Support: IE<9
-	support.getElementsByClassName = rnative.test( document.getElementsByClassName );
-
-	// Support: IE<10
-	// Check if getElementById returns elements by name
-	// The broken getElementById methods don't pick up programmatically-set names,
-	// so use a roundabout getElementsByName test
-	support.getById = assert(function( el ) {
-		docElem.appendChild( el ).id = expando;
-		return !document.getElementsByName || !document.getElementsByName( expando ).length;
-	});
-
-	// ID filter and find
-	if ( support.getById ) {
-		Expr.filter["ID"] = function( id ) {
-			var attrId = id.replace( runescape, funescape );
-			return function( elem ) {
-				return elem.getAttribute("id") === attrId;
-			};
-		};
-		Expr.find["ID"] = function( id, context ) {
-			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
-				var elem = context.getElementById( id );
-				return elem ? [ elem ] : [];
-			}
-		};
-	} else {
-		Expr.filter["ID"] =  function( id ) {
-			var attrId = id.replace( runescape, funescape );
-			return function( elem ) {
-				var node = typeof elem.getAttributeNode !== "undefined" &&
-					elem.getAttributeNode("id");
-				return node && node.value === attrId;
-			};
-		};
-
-		// Support: IE 6 - 7 only
-		// getElementById is not reliable as a find shortcut
-		Expr.find["ID"] = function( id, context ) {
-			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
-				var node, i, elems,
-					elem = context.getElementById( id );
-
-				if ( elem ) {
-
-					// Verify the id attribute
-					node = elem.getAttributeNode("id");
-					if ( node && node.value === id ) {
-						return [ elem ];
-					}
-
-					// Fall back on getElementsByName
-					elems = context.getElementsByName( id );
-					i = 0;
-					while ( (elem = elems[i++]) ) {
-						node = elem.getAttributeNode("id");
-						if ( node && node.value === id ) {
-							return [ elem ];
-						}
-					}
-				}
-
-				return [];
-			}
-		};
-	}
-
-	// Tag
-	Expr.find["TAG"] = support.getElementsByTagName ?
-		function( tag, context ) {
-			if ( typeof context.getElementsByTagName !== "undefined" ) {
-				return context.getElementsByTagName( tag );
-
-			// DocumentFragment nodes don't have gEBTN
-			} else if ( support.qsa ) {
-				return context.querySelectorAll( tag );
-			}
-		} :
-
-		function( tag, context ) {
-			var elem,
-				tmp = [],
-				i = 0,
-				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
-				results = context.getElementsByTagName( tag );
-
-			// Filter out possible comments
-			if ( tag === "*" ) {
-				while ( (elem = results[i++]) ) {
-					if ( elem.nodeType === 1 ) {
-						tmp.push( elem );
-					}
-				}
-
-				return tmp;
-			}
-			return results;
-		};
-
-	// Class
-	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
-		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
-			return context.getElementsByClassName( className );
-		}
-	};
-
-	/* QSA/matchesSelector
-	---------------------------------------------------------------------- */
-
-	// QSA and matchesSelector support
-
-	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
-	rbuggyMatches = [];
-
-	// qSa(:focus) reports false when true (Chrome 21)
-	// We allow this because of a bug in IE8/9 that throws an error
-	// whenever `document.activeElement` is accessed on an iframe
-	// So, we allow :focus to pass through QSA all the time to avoid the IE error
-	// See https://bugs.jquery.com/ticket/13378
-	rbuggyQSA = [];
-
-	if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
-		// Build QSA regex
-		// Regex strategy adopted from Diego Perini
-		assert(function( el ) {
-			// Select is set to empty string on purpose
-			// This is to test IE's treatment of not explicitly
-			// setting a boolean content attribute,
-			// since its presence should be enough
-			// https://bugs.jquery.com/ticket/12359
-			docElem.appendChild( el ).innerHTML = "" +
-				"";
-
-			// Support: IE8, Opera 11-12.16
-			// Nothing should be selected when empty strings follow ^= or $= or *=
-			// The test attribute must be unknown in Opera but "safe" for WinRT
-			// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
-			if ( el.querySelectorAll("[msallowcapture^='']").length ) {
-				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
-			}
-
-			// Support: IE8
-			// Boolean attributes and "value" are not treated correctly
-			if ( !el.querySelectorAll("[selected]").length ) {
-				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
-			}
-
-			// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
-			if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
-				rbuggyQSA.push("~=");
-			}
-
-			// Webkit/Opera - :checked should return selected option elements
-			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
-			// IE8 throws error here and will not see later tests
-			if ( !el.querySelectorAll(":checked").length ) {
-				rbuggyQSA.push(":checked");
-			}
-
-			// Support: Safari 8+, iOS 8+
-			// https://bugs.webkit.org/show_bug.cgi?id=136851
-			// In-page `selector#id sibling-combinator selector` fails
-			if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
-				rbuggyQSA.push(".#.+[+~]");
-			}
-		});
-
-		assert(function( el ) {
-			el.innerHTML = "" +
-				"";
-
-			// Support: Windows 8 Native Apps
-			// The type and name attributes are restricted during .innerHTML assignment
-			var input = document.createElement("input");
-			input.setAttribute( "type", "hidden" );
-			el.appendChild( input ).setAttribute( "name", "D" );
-
-			// Support: IE8
-			// Enforce case-sensitivity of name attribute
-			if ( el.querySelectorAll("[name=d]").length ) {
-				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
-			}
-
-			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
-			// IE8 throws error here and will not see later tests
-			if ( el.querySelectorAll(":enabled").length !== 2 ) {
-				rbuggyQSA.push( ":enabled", ":disabled" );
-			}
-
-			// Support: IE9-11+
-			// IE's :disabled selector does not pick up the children of disabled fieldsets
-			docElem.appendChild( el ).disabled = true;
-			if ( el.querySelectorAll(":disabled").length !== 2 ) {
-				rbuggyQSA.push( ":enabled", ":disabled" );
-			}
-
-			// Opera 10-11 does not throw on post-comma invalid pseudos
-			el.querySelectorAll("*,:x");
-			rbuggyQSA.push(",.*:");
-		});
-	}
-
-	if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
-		docElem.webkitMatchesSelector ||
-		docElem.mozMatchesSelector ||
-		docElem.oMatchesSelector ||
-		docElem.msMatchesSelector) )) ) {
-
-		assert(function( el ) {
-			// Check to see if it's possible to do matchesSelector
-			// on a disconnected node (IE 9)
-			support.disconnectedMatch = matches.call( el, "*" );
-
-			// This should fail with an exception
-			// Gecko does not error, returns false instead
-			matches.call( el, "[s!='']:x" );
-			rbuggyMatches.push( "!=", pseudos );
-		});
-	}
-
-	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
-	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
-
-	/* Contains
-	---------------------------------------------------------------------- */
-	hasCompare = rnative.test( docElem.compareDocumentPosition );
-
-	// Element contains another
-	// Purposefully self-exclusive
-	// As in, an element does not contain itself
-	contains = hasCompare || rnative.test( docElem.contains ) ?
-		function( a, b ) {
-			var adown = a.nodeType === 9 ? a.documentElement : a,
-				bup = b && b.parentNode;
-			return a === bup || !!( bup && bup.nodeType === 1 && (
-				adown.contains ?
-					adown.contains( bup ) :
-					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
-			));
-		} :
-		function( a, b ) {
-			if ( b ) {
-				while ( (b = b.parentNode) ) {
-					if ( b === a ) {
-						return true;
-					}
-				}
-			}
-			return false;
-		};
-
-	/* Sorting
-	---------------------------------------------------------------------- */
-
-	// Document order sorting
-	sortOrder = hasCompare ?
-	function( a, b ) {
-
-		// Flag for duplicate removal
-		if ( a === b ) {
-			hasDuplicate = true;
-			return 0;
-		}
-
-		// Sort on method existence if only one input has compareDocumentPosition
-		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
-		if ( compare ) {
-			return compare;
-		}
-
-		// Calculate position if both inputs belong to the same document
-		compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
-			a.compareDocumentPosition( b ) :
-
-			// Otherwise we know they are disconnected
-			1;
-
-		// Disconnected nodes
-		if ( compare & 1 ||
-			(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
-
-			// Choose the first element that is related to our preferred document
-			if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
-				return -1;
-			}
-			if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
-				return 1;
-			}
-
-			// Maintain original order
-			return sortInput ?
-				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
-				0;
-		}
-
-		return compare & 4 ? -1 : 1;
-	} :
-	function( a, b ) {
-		// Exit early if the nodes are identical
-		if ( a === b ) {
-			hasDuplicate = true;
-			return 0;
-		}
-
-		var cur,
-			i = 0,
-			aup = a.parentNode,
-			bup = b.parentNode,
-			ap = [ a ],
-			bp = [ b ];
-
-		// Parentless nodes are either documents or disconnected
-		if ( !aup || !bup ) {
-			return a === document ? -1 :
-				b === document ? 1 :
-				aup ? -1 :
-				bup ? 1 :
-				sortInput ?
-				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
-				0;
-
-		// If the nodes are siblings, we can do a quick check
-		} else if ( aup === bup ) {
-			return siblingCheck( a, b );
-		}
-
-		// Otherwise we need full lists of their ancestors for comparison
-		cur = a;
-		while ( (cur = cur.parentNode) ) {
-			ap.unshift( cur );
-		}
-		cur = b;
-		while ( (cur = cur.parentNode) ) {
-			bp.unshift( cur );
-		}
-
-		// Walk down the tree looking for a discrepancy
-		while ( ap[i] === bp[i] ) {
-			i++;
-		}
-
-		return i ?
-			// Do a sibling check if the nodes have a common ancestor
-			siblingCheck( ap[i], bp[i] ) :
-
-			// Otherwise nodes in our document sort first
-			ap[i] === preferredDoc ? -1 :
-			bp[i] === preferredDoc ? 1 :
-			0;
-	};
-
-	return document;
-};
-
-Sizzle.matches = function( expr, elements ) {
-	return Sizzle( expr, null, null, elements );
-};
-
-Sizzle.matchesSelector = function( elem, expr ) {
-	// Set document vars if needed
-	if ( ( elem.ownerDocument || elem ) !== document ) {
-		setDocument( elem );
-	}
-
-	// Make sure that attribute selectors are quoted
-	expr = expr.replace( rattributeQuotes, "='$1']" );
-
-	if ( support.matchesSelector && documentIsHTML &&
-		!compilerCache[ expr + " " ] &&
-		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
-		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
-
-		try {
-			var ret = matches.call( elem, expr );
-
-			// IE 9's matchesSelector returns false on disconnected nodes
-			if ( ret || support.disconnectedMatch ||
-					// As well, disconnected nodes are said to be in a document
-					// fragment in IE 9
-					elem.document && elem.document.nodeType !== 11 ) {
-				return ret;
-			}
-		} catch (e) {}
-	}
-
-	return Sizzle( expr, document, null, [ elem ] ).length > 0;
-};
-
-Sizzle.contains = function( context, elem ) {
-	// Set document vars if needed
-	if ( ( context.ownerDocument || context ) !== document ) {
-		setDocument( context );
-	}
-	return contains( context, elem );
-};
-
-Sizzle.attr = function( elem, name ) {
-	// Set document vars if needed
-	if ( ( elem.ownerDocument || elem ) !== document ) {
-		setDocument( elem );
-	}
-
-	var fn = Expr.attrHandle[ name.toLowerCase() ],
-		// Don't get fooled by Object.prototype properties (jQuery #13807)
-		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
-			fn( elem, name, !documentIsHTML ) :
-			undefined;
-
-	return val !== undefined ?
-		val :
-		support.attributes || !documentIsHTML ?
-			elem.getAttribute( name ) :
-			(val = elem.getAttributeNode(name)) && val.specified ?
-				val.value :
-				null;
-};
-
-Sizzle.escape = function( sel ) {
-	return (sel + "").replace( rcssescape, fcssescape );
-};
-
-Sizzle.error = function( msg ) {
-	throw new Error( "Syntax error, unrecognized expression: " + msg );
-};
-
-/**
- * Document sorting and removing duplicates
- * @param {ArrayLike} results
- */
-Sizzle.uniqueSort = function( results ) {
-	var elem,
-		duplicates = [],
-		j = 0,
-		i = 0;
-
-	// Unless we *know* we can detect duplicates, assume their presence
-	hasDuplicate = !support.detectDuplicates;
-	sortInput = !support.sortStable && results.slice( 0 );
-	results.sort( sortOrder );
-
-	if ( hasDuplicate ) {
-		while ( (elem = results[i++]) ) {
-			if ( elem === results[ i ] ) {
-				j = duplicates.push( i );
-			}
-		}
-		while ( j-- ) {
-			results.splice( duplicates[ j ], 1 );
-		}
-	}
-
-	// Clear input after sorting to release objects
-	// See https://github.com/jquery/sizzle/pull/225
-	sortInput = null;
-
-	return results;
-};
-
-/**
- * Utility function for retrieving the text value of an array of DOM nodes
- * @param {Array|Element} elem
- */
-getText = Sizzle.getText = function( elem ) {
-	var node,
-		ret = "",
-		i = 0,
-		nodeType = elem.nodeType;
-
-	if ( !nodeType ) {
-		// If no nodeType, this is expected to be an array
-		while ( (node = elem[i++]) ) {
-			// Do not traverse comment nodes
-			ret += getText( node );
-		}
-	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
-		// Use textContent for elements
-		// innerText usage removed for consistency of new lines (jQuery #11153)
-		if ( typeof elem.textContent === "string" ) {
-			return elem.textContent;
-		} else {
-			// Traverse its children
-			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
-				ret += getText( elem );
-			}
-		}
-	} else if ( nodeType === 3 || nodeType === 4 ) {
-		return elem.nodeValue;
-	}
-	// Do not include comment or processing instruction nodes
-
-	return ret;
-};
-
-Expr = Sizzle.selectors = {
-
-	// Can be adjusted by the user
-	cacheLength: 50,
-
-	createPseudo: markFunction,
-
-	match: matchExpr,
-
-	attrHandle: {},
-
-	find: {},
-
-	relative: {
-		">": { dir: "parentNode", first: true },
-		" ": { dir: "parentNode" },
-		"+": { dir: "previousSibling", first: true },
-		"~": { dir: "previousSibling" }
-	},
-
-	preFilter: {
-		"ATTR": function( match ) {
-			match[1] = match[1].replace( runescape, funescape );
-
-			// Move the given value to match[3] whether quoted or unquoted
-			match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
-
-			if ( match[2] === "~=" ) {
-				match[3] = " " + match[3] + " ";
-			}
-
-			return match.slice( 0, 4 );
-		},
-
-		"CHILD": function( match ) {
-			/* matches from matchExpr["CHILD"]
-				1 type (only|nth|...)
-				2 what (child|of-type)
-				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
-				4 xn-component of xn+y argument ([+-]?\d*n|)
-				5 sign of xn-component
-				6 x of xn-component
-				7 sign of y-component
-				8 y of y-component
-			*/
-			match[1] = match[1].toLowerCase();
-
-			if ( match[1].slice( 0, 3 ) === "nth" ) {
-				// nth-* requires argument
-				if ( !match[3] ) {
-					Sizzle.error( match[0] );
-				}
-
-				// numeric x and y parameters for Expr.filter.CHILD
-				// remember that false/true cast respectively to 0/1
-				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
-				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
-
-			// other types prohibit arguments
-			} else if ( match[3] ) {
-				Sizzle.error( match[0] );
-			}
-
-			return match;
-		},
-
-		"PSEUDO": function( match ) {
-			var excess,
-				unquoted = !match[6] && match[2];
-
-			if ( matchExpr["CHILD"].test( match[0] ) ) {
-				return null;
-			}
-
-			// Accept quoted arguments as-is
-			if ( match[3] ) {
-				match[2] = match[4] || match[5] || "";
-
-			// Strip excess characters from unquoted arguments
-			} else if ( unquoted && rpseudo.test( unquoted ) &&
-				// Get excess from tokenize (recursively)
-				(excess = tokenize( unquoted, true )) &&
-				// advance to the next closing parenthesis
-				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
-
-				// excess is a negative index
-				match[0] = match[0].slice( 0, excess );
-				match[2] = unquoted.slice( 0, excess );
-			}
-
-			// Return only captures needed by the pseudo filter method (type and argument)
-			return match.slice( 0, 3 );
-		}
-	},
-
-	filter: {
-
-		"TAG": function( nodeNameSelector ) {
-			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
-			return nodeNameSelector === "*" ?
-				function() { return true; } :
-				function( elem ) {
-					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
-				};
-		},
-
-		"CLASS": function( className ) {
-			var pattern = classCache[ className + " " ];
-
-			return pattern ||
-				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
-				classCache( className, function( elem ) {
-					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
-				});
-		},
-
-		"ATTR": function( name, operator, check ) {
-			return function( elem ) {
-				var result = Sizzle.attr( elem, name );
-
-				if ( result == null ) {
-					return operator === "!=";
-				}
-				if ( !operator ) {
-					return true;
-				}
-
-				result += "";
-
-				return operator === "=" ? result === check :
-					operator === "!=" ? result !== check :
-					operator === "^=" ? check && result.indexOf( check ) === 0 :
-					operator === "*=" ? check && result.indexOf( check ) > -1 :
-					operator === "$=" ? check && result.slice( -check.length ) === check :
-					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
-					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
-					false;
-			};
-		},
-
-		"CHILD": function( type, what, argument, first, last ) {
-			var simple = type.slice( 0, 3 ) !== "nth",
-				forward = type.slice( -4 ) !== "last",
-				ofType = what === "of-type";
-
-			return first === 1 && last === 0 ?
-
-				// Shortcut for :nth-*(n)
-				function( elem ) {
-					return !!elem.parentNode;
-				} :
-
-				function( elem, context, xml ) {
-					var cache, uniqueCache, outerCache, node, nodeIndex, start,
-						dir = simple !== forward ? "nextSibling" : "previousSibling",
-						parent = elem.parentNode,
-						name = ofType && elem.nodeName.toLowerCase(),
-						useCache = !xml && !ofType,
-						diff = false;
-
-					if ( parent ) {
-
-						// :(first|last|only)-(child|of-type)
-						if ( simple ) {
-							while ( dir ) {
-								node = elem;
-								while ( (node = node[ dir ]) ) {
-									if ( ofType ?
-										node.nodeName.toLowerCase() === name :
-										node.nodeType === 1 ) {
-
-										return false;
-									}
-								}
-								// Reverse direction for :only-* (if we haven't yet done so)
-								start = dir = type === "only" && !start && "nextSibling";
-							}
-							return true;
-						}
-
-						start = [ forward ? parent.firstChild : parent.lastChild ];
-
-						// non-xml :nth-child(...) stores cache data on `parent`
-						if ( forward && useCache ) {
-
-							// Seek `elem` from a previously-cached index
-
-							// ...in a gzip-friendly way
-							node = parent;
-							outerCache = node[ expando ] || (node[ expando ] = {});
-
-							// Support: IE <9 only
-							// Defend against cloned attroperties (jQuery gh-1709)
-							uniqueCache = outerCache[ node.uniqueID ] ||
-								(outerCache[ node.uniqueID ] = {});
-
-							cache = uniqueCache[ type ] || [];
-							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
-							diff = nodeIndex && cache[ 2 ];
-							node = nodeIndex && parent.childNodes[ nodeIndex ];
-
-							while ( (node = ++nodeIndex && node && node[ dir ] ||
-
-								// Fallback to seeking `elem` from the start
-								(diff = nodeIndex = 0) || start.pop()) ) {
-
-								// When found, cache indexes on `parent` and break
-								if ( node.nodeType === 1 && ++diff && node === elem ) {
-									uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
-									break;
-								}
-							}
-
-						} else {
-							// Use previously-cached element index if available
-							if ( useCache ) {
-								// ...in a gzip-friendly way
-								node = elem;
-								outerCache = node[ expando ] || (node[ expando ] = {});
-
-								// Support: IE <9 only
-								// Defend against cloned attroperties (jQuery gh-1709)
-								uniqueCache = outerCache[ node.uniqueID ] ||
-									(outerCache[ node.uniqueID ] = {});
-
-								cache = uniqueCache[ type ] || [];
-								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
-								diff = nodeIndex;
-							}
-
-							// xml :nth-child(...)
-							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
-							if ( diff === false ) {
-								// Use the same loop as above to seek `elem` from the start
-								while ( (node = ++nodeIndex && node && node[ dir ] ||
-									(diff = nodeIndex = 0) || start.pop()) ) {
-
-									if ( ( ofType ?
-										node.nodeName.toLowerCase() === name :
-										node.nodeType === 1 ) &&
-										++diff ) {
-
-										// Cache the index of each encountered element
-										if ( useCache ) {
-											outerCache = node[ expando ] || (node[ expando ] = {});
-
-											// Support: IE <9 only
-											// Defend against cloned attroperties (jQuery gh-1709)
-											uniqueCache = outerCache[ node.uniqueID ] ||
-												(outerCache[ node.uniqueID ] = {});
-
-											uniqueCache[ type ] = [ dirruns, diff ];
-										}
-
-										if ( node === elem ) {
-											break;
-										}
-									}
-								}
-							}
-						}
-
-						// Incorporate the offset, then check against cycle size
-						diff -= last;
-						return diff === first || ( diff % first === 0 && diff / first >= 0 );
-					}
-				};
-		},
-
-		"PSEUDO": function( pseudo, argument ) {
-			// pseudo-class names are case-insensitive
-			// http://www.w3.org/TR/selectors/#pseudo-classes
-			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
-			// Remember that setFilters inherits from pseudos
-			var args,
-				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
-					Sizzle.error( "unsupported pseudo: " + pseudo );
-
-			// The user may use createPseudo to indicate that
-			// arguments are needed to create the filter function
-			// just as Sizzle does
-			if ( fn[ expando ] ) {
-				return fn( argument );
-			}
-
-			// But maintain support for old signatures
-			if ( fn.length > 1 ) {
-				args = [ pseudo, pseudo, "", argument ];
-				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
-					markFunction(function( seed, matches ) {
-						var idx,
-							matched = fn( seed, argument ),
-							i = matched.length;
-						while ( i-- ) {
-							idx = indexOf( seed, matched[i] );
-							seed[ idx ] = !( matches[ idx ] = matched[i] );
-						}
-					}) :
-					function( elem ) {
-						return fn( elem, 0, args );
-					};
-			}
-
-			return fn;
-		}
-	},
-
-	pseudos: {
-		// Potentially complex pseudos
-		"not": markFunction(function( selector ) {
-			// Trim the selector passed to compile
-			// to avoid treating leading and trailing
-			// spaces as combinators
-			var input = [],
-				results = [],
-				matcher = compile( selector.replace( rtrim, "$1" ) );
-
-			return matcher[ expando ] ?
-				markFunction(function( seed, matches, context, xml ) {
-					var elem,
-						unmatched = matcher( seed, null, xml, [] ),
-						i = seed.length;
-
-					// Match elements unmatched by `matcher`
-					while ( i-- ) {
-						if ( (elem = unmatched[i]) ) {
-							seed[i] = !(matches[i] = elem);
-						}
-					}
-				}) :
-				function( elem, context, xml ) {
-					input[0] = elem;
-					matcher( input, null, xml, results );
-					// Don't keep the element (issue #299)
-					input[0] = null;
-					return !results.pop();
-				};
-		}),
-
-		"has": markFunction(function( selector ) {
-			return function( elem ) {
-				return Sizzle( selector, elem ).length > 0;
-			};
-		}),
-
-		"contains": markFunction(function( text ) {
-			text = text.replace( runescape, funescape );
-			return function( elem ) {
-				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
-			};
-		}),
-
-		// "Whether an element is represented by a :lang() selector
-		// is based solely on the element's language value
-		// being equal to the identifier C,
-		// or beginning with the identifier C immediately followed by "-".
-		// The matching of C against the element's language value is performed case-insensitively.
-		// The identifier C does not have to be a valid language name."
-		// http://www.w3.org/TR/selectors/#lang-pseudo
-		"lang": markFunction( function( lang ) {
-			// lang value must be a valid identifier
-			if ( !ridentifier.test(lang || "") ) {
-				Sizzle.error( "unsupported lang: " + lang );
-			}
-			lang = lang.replace( runescape, funescape ).toLowerCase();
-			return function( elem ) {
-				var elemLang;
-				do {
-					if ( (elemLang = documentIsHTML ?
-						elem.lang :
-						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
-
-						elemLang = elemLang.toLowerCase();
-						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
-					}
-				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
-				return false;
-			};
-		}),
-
-		// Miscellaneous
-		"target": function( elem ) {
-			var hash = window.location && window.location.hash;
-			return hash && hash.slice( 1 ) === elem.id;
-		},
-
-		"root": function( elem ) {
-			return elem === docElem;
-		},
-
-		"focus": function( elem ) {
-			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
-		},
-
-		// Boolean properties
-		"enabled": createDisabledPseudo( false ),
-		"disabled": createDisabledPseudo( true ),
-
-		"checked": function( elem ) {
-			// In CSS3, :checked should return both checked and selected elements
-			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
-			var nodeName = elem.nodeName.toLowerCase();
-			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
-		},
-
-		"selected": function( elem ) {
-			// Accessing this property makes selected-by-default
-			// options in Safari work properly
-			if ( elem.parentNode ) {
-				elem.parentNode.selectedIndex;
-			}
-
-			return elem.selected === true;
-		},
-
-		// Contents
-		"empty": function( elem ) {
-			// http://www.w3.org/TR/selectors/#empty-pseudo
-			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
-			//   but not by others (comment: 8; processing instruction: 7; etc.)
-			// nodeType < 6 works because attributes (2) do not appear as children
-			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
-				if ( elem.nodeType < 6 ) {
-					return false;
-				}
-			}
-			return true;
-		},
-
-		"parent": function( elem ) {
-			return !Expr.pseudos["empty"]( elem );
-		},
-
-		// Element/input types
-		"header": function( elem ) {
-			return rheader.test( elem.nodeName );
-		},
-
-		"input": function( elem ) {
-			return rinputs.test( elem.nodeName );
-		},
-
-		"button": function( elem ) {
-			var name = elem.nodeName.toLowerCase();
-			return name === "input" && elem.type === "button" || name === "button";
-		},
-
-		"text": function( elem ) {
-			var attr;
-			return elem.nodeName.toLowerCase() === "input" &&
-				elem.type === "text" &&
-
-				// Support: IE<8
-				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
-				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
-		},
-
-		// Position-in-collection
-		"first": createPositionalPseudo(function() {
-			return [ 0 ];
-		}),
-
-		"last": createPositionalPseudo(function( matchIndexes, length ) {
-			return [ length - 1 ];
-		}),
-
-		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
-			return [ argument < 0 ? argument + length : argument ];
-		}),
-
-		"even": createPositionalPseudo(function( matchIndexes, length ) {
-			var i = 0;
-			for ( ; i < length; i += 2 ) {
-				matchIndexes.push( i );
-			}
-			return matchIndexes;
-		}),
-
-		"odd": createPositionalPseudo(function( matchIndexes, length ) {
-			var i = 1;
-			for ( ; i < length; i += 2 ) {
-				matchIndexes.push( i );
-			}
-			return matchIndexes;
-		}),
-
-		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
-			var i = argument < 0 ? argument + length : argument;
-			for ( ; --i >= 0; ) {
-				matchIndexes.push( i );
-			}
-			return matchIndexes;
-		}),
-
-		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
-			var i = argument < 0 ? argument + length : argument;
-			for ( ; ++i < length; ) {
-				matchIndexes.push( i );
-			}
-			return matchIndexes;
-		})
-	}
-};
-
-Expr.pseudos["nth"] = Expr.pseudos["eq"];
-
-// Add button/input type pseudos
-for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
-	Expr.pseudos[ i ] = createInputPseudo( i );
-}
-for ( i in { submit: true, reset: true } ) {
-	Expr.pseudos[ i ] = createButtonPseudo( i );
-}
-
-// Easy API for creating new setFilters
-function setFilters() {}
-setFilters.prototype = Expr.filters = Expr.pseudos;
-Expr.setFilters = new setFilters();
-
-tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
-	var matched, match, tokens, type,
-		soFar, groups, preFilters,
-		cached = tokenCache[ selector + " " ];
-
-	if ( cached ) {
-		return parseOnly ? 0 : cached.slice( 0 );
-	}
-
-	soFar = selector;
-	groups = [];
-	preFilters = Expr.preFilter;
-
-	while ( soFar ) {
-
-		// Comma and first run
-		if ( !matched || (match = rcomma.exec( soFar )) ) {
-			if ( match ) {
-				// Don't consume trailing commas as valid
-				soFar = soFar.slice( match[0].length ) || soFar;
-			}
-			groups.push( (tokens = []) );
-		}
-
-		matched = false;
-
-		// Combinators
-		if ( (match = rcombinators.exec( soFar )) ) {
-			matched = match.shift();
-			tokens.push({
-				value: matched,
-				// Cast descendant combinators to space
-				type: match[0].replace( rtrim, " " )
-			});
-			soFar = soFar.slice( matched.length );
-		}
-
-		// Filters
-		for ( type in Expr.filter ) {
-			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
-				(match = preFilters[ type ]( match ))) ) {
-				matched = match.shift();
-				tokens.push({
-					value: matched,
-					type: type,
-					matches: match
-				});
-				soFar = soFar.slice( matched.length );
-			}
-		}
-
-		if ( !matched ) {
-			break;
-		}
-	}
-
-	// Return the length of the invalid excess
-	// if we're just parsing
-	// Otherwise, throw an error or return tokens
-	return parseOnly ?
-		soFar.length :
-		soFar ?
-			Sizzle.error( selector ) :
-			// Cache the tokens
-			tokenCache( selector, groups ).slice( 0 );
-};
-
-function toSelector( tokens ) {
-	var i = 0,
-		len = tokens.length,
-		selector = "";
-	for ( ; i < len; i++ ) {
-		selector += tokens[i].value;
-	}
-	return selector;
-}
-
-function addCombinator( matcher, combinator, base ) {
-	var dir = combinator.dir,
-		skip = combinator.next,
-		key = skip || dir,
-		checkNonElements = base && key === "parentNode",
-		doneName = done++;
-
-	return combinator.first ?
-		// Check against closest ancestor/preceding element
-		function( elem, context, xml ) {
-			while ( (elem = elem[ dir ]) ) {
-				if ( elem.nodeType === 1 || checkNonElements ) {
-					return matcher( elem, context, xml );
-				}
-			}
-			return false;
-		} :
-
-		// Check against all ancestor/preceding elements
-		function( elem, context, xml ) {
-			var oldCache, uniqueCache, outerCache,
-				newCache = [ dirruns, doneName ];
-
-			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
-			if ( xml ) {
-				while ( (elem = elem[ dir ]) ) {
-					if ( elem.nodeType === 1 || checkNonElements ) {
-						if ( matcher( elem, context, xml ) ) {
-							return true;
-						}
-					}
-				}
-			} else {
-				while ( (elem = elem[ dir ]) ) {
-					if ( elem.nodeType === 1 || checkNonElements ) {
-						outerCache = elem[ expando ] || (elem[ expando ] = {});
-
-						// Support: IE <9 only
-						// Defend against cloned attroperties (jQuery gh-1709)
-						uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
-
-						if ( skip && skip === elem.nodeName.toLowerCase() ) {
-							elem = elem[ dir ] || elem;
-						} else if ( (oldCache = uniqueCache[ key ]) &&
-							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
-
-							// Assign to newCache so results back-propagate to previous elements
-							return (newCache[ 2 ] = oldCache[ 2 ]);
-						} else {
-							// Reuse newcache so results back-propagate to previous elements
-							uniqueCache[ key ] = newCache;
-
-							// A match means we're done; a fail means we have to keep checking
-							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
-								return true;
-							}
-						}
-					}
-				}
-			}
-			return false;
-		};
-}
-
-function elementMatcher( matchers ) {
-	return matchers.length > 1 ?
-		function( elem, context, xml ) {
-			var i = matchers.length;
-			while ( i-- ) {
-				if ( !matchers[i]( elem, context, xml ) ) {
-					return false;
-				}
-			}
-			return true;
-		} :
-		matchers[0];
-}
-
-function multipleContexts( selector, contexts, results ) {
-	var i = 0,
-		len = contexts.length;
-	for ( ; i < len; i++ ) {
-		Sizzle( selector, contexts[i], results );
-	}
-	return results;
-}
-
-function condense( unmatched, map, filter, context, xml ) {
-	var elem,
-		newUnmatched = [],
-		i = 0,
-		len = unmatched.length,
-		mapped = map != null;
-
-	for ( ; i < len; i++ ) {
-		if ( (elem = unmatched[i]) ) {
-			if ( !filter || filter( elem, context, xml ) ) {
-				newUnmatched.push( elem );
-				if ( mapped ) {
-					map.push( i );
-				}
-			}
-		}
-	}
-
-	return newUnmatched;
-}
-
-function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
-	if ( postFilter && !postFilter[ expando ] ) {
-		postFilter = setMatcher( postFilter );
-	}
-	if ( postFinder && !postFinder[ expando ] ) {
-		postFinder = setMatcher( postFinder, postSelector );
-	}
-	return markFunction(function( seed, results, context, xml ) {
-		var temp, i, elem,
-			preMap = [],
-			postMap = [],
-			preexisting = results.length,
-
-			// Get initial elements from seed or context
-			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
-
-			// Prefilter to get matcher input, preserving a map for seed-results synchronization
-			matcherIn = preFilter && ( seed || !selector ) ?
-				condense( elems, preMap, preFilter, context, xml ) :
-				elems,
-
-			matcherOut = matcher ?
-				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
-				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
-
-					// ...intermediate processing is necessary
-					[] :
-
-					// ...otherwise use results directly
-					results :
-				matcherIn;
-
-		// Find primary matches
-		if ( matcher ) {
-			matcher( matcherIn, matcherOut, context, xml );
-		}
-
-		// Apply postFilter
-		if ( postFilter ) {
-			temp = condense( matcherOut, postMap );
-			postFilter( temp, [], context, xml );
-
-			// Un-match failing elements by moving them back to matcherIn
-			i = temp.length;
-			while ( i-- ) {
-				if ( (elem = temp[i]) ) {
-					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
-				}
-			}
-		}
-
-		if ( seed ) {
-			if ( postFinder || preFilter ) {
-				if ( postFinder ) {
-					// Get the final matcherOut by condensing this intermediate into postFinder contexts
-					temp = [];
-					i = matcherOut.length;
-					while ( i-- ) {
-						if ( (elem = matcherOut[i]) ) {
-							// Restore matcherIn since elem is not yet a final match
-							temp.push( (matcherIn[i] = elem) );
-						}
-					}
-					postFinder( null, (matcherOut = []), temp, xml );
-				}
-
-				// Move matched elements from seed to results to keep them synchronized
-				i = matcherOut.length;
-				while ( i-- ) {
-					if ( (elem = matcherOut[i]) &&
-						(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
-
-						seed[temp] = !(results[temp] = elem);
-					}
-				}
-			}
-
-		// Add elements to results, through postFinder if defined
-		} else {
-			matcherOut = condense(
-				matcherOut === results ?
-					matcherOut.splice( preexisting, matcherOut.length ) :
-					matcherOut
-			);
-			if ( postFinder ) {
-				postFinder( null, results, matcherOut, xml );
-			} else {
-				push.apply( results, matcherOut );
-			}
-		}
-	});
-}
-
-function matcherFromTokens( tokens ) {
-	var checkContext, matcher, j,
-		len = tokens.length,
-		leadingRelative = Expr.relative[ tokens[0].type ],
-		implicitRelative = leadingRelative || Expr.relative[" "],
-		i = leadingRelative ? 1 : 0,
-
-		// The foundational matcher ensures that elements are reachable from top-level context(s)
-		matchContext = addCombinator( function( elem ) {
-			return elem === checkContext;
-		}, implicitRelative, true ),
-		matchAnyContext = addCombinator( function( elem ) {
-			return indexOf( checkContext, elem ) > -1;
-		}, implicitRelative, true ),
-		matchers = [ function( elem, context, xml ) {
-			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
-				(checkContext = context).nodeType ?
-					matchContext( elem, context, xml ) :
-					matchAnyContext( elem, context, xml ) );
-			// Avoid hanging onto element (issue #299)
-			checkContext = null;
-			return ret;
-		} ];
-
-	for ( ; i < len; i++ ) {
-		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
-			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
-		} else {
-			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
-
-			// Return special upon seeing a positional matcher
-			if ( matcher[ expando ] ) {
-				// Find the next relative operator (if any) for proper handling
-				j = ++i;
-				for ( ; j < len; j++ ) {
-					if ( Expr.relative[ tokens[j].type ] ) {
-						break;
-					}
-				}
-				return setMatcher(
-					i > 1 && elementMatcher( matchers ),
-					i > 1 && toSelector(
-						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
-						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
-					).replace( rtrim, "$1" ),
-					matcher,
-					i < j && matcherFromTokens( tokens.slice( i, j ) ),
-					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
-					j < len && toSelector( tokens )
-				);
-			}
-			matchers.push( matcher );
-		}
-	}
-
-	return elementMatcher( matchers );
-}
-
-function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
-	var bySet = setMatchers.length > 0,
-		byElement = elementMatchers.length > 0,
-		superMatcher = function( seed, context, xml, results, outermost ) {
-			var elem, j, matcher,
-				matchedCount = 0,
-				i = "0",
-				unmatched = seed && [],
-				setMatched = [],
-				contextBackup = outermostContext,
-				// We must always have either seed elements or outermost context
-				elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
-				// Use integer dirruns iff this is the outermost matcher
-				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
-				len = elems.length;
-
-			if ( outermost ) {
-				outermostContext = context === document || context || outermost;
-			}
-
-			// Add elements passing elementMatchers directly to results
-			// Support: IE<9, Safari
-			// Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id
-			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
-				if ( byElement && elem ) {
-					j = 0;
-					if ( !context && elem.ownerDocument !== document ) {
-						setDocument( elem );
-						xml = !documentIsHTML;
-					}
-					while ( (matcher = elementMatchers[j++]) ) {
-						if ( matcher( elem, context || document, xml) ) {
-							results.push( elem );
-							break;
-						}
-					}
-					if ( outermost ) {
-						dirruns = dirrunsUnique;
-					}
-				}
-
-				// Track unmatched elements for set filters
-				if ( bySet ) {
-					// They will have gone through all possible matchers
-					if ( (elem = !matcher && elem) ) {
-						matchedCount--;
-					}
-
-					// Lengthen the array for every element, matched or not
-					if ( seed ) {
-						unmatched.push( elem );
-					}
-				}
-			}
-
-			// `i` is now the count of elements visited above, and adding it to `matchedCount`
-			// makes the latter nonnegative.
-			matchedCount += i;
-
-			// Apply set filters to unmatched elements
-			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
-			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
-			// no element matchers and no seed.
-			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
-			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
-			// numerically zero.
-			if ( bySet && i !== matchedCount ) {
-				j = 0;
-				while ( (matcher = setMatchers[j++]) ) {
-					matcher( unmatched, setMatched, context, xml );
-				}
-
-				if ( seed ) {
-					// Reintegrate element matches to eliminate the need for sorting
-					if ( matchedCount > 0 ) {
-						while ( i-- ) {
-							if ( !(unmatched[i] || setMatched[i]) ) {
-								setMatched[i] = pop.call( results );
-							}
-						}
-					}
-
-					// Discard index placeholder values to get only actual matches
-					setMatched = condense( setMatched );
-				}
-
-				// Add matches to results
-				push.apply( results, setMatched );
-
-				// Seedless set matches succeeding multiple successful matchers stipulate sorting
-				if ( outermost && !seed && setMatched.length > 0 &&
-					( matchedCount + setMatchers.length ) > 1 ) {
-
-					Sizzle.uniqueSort( results );
-				}
-			}
-
-			// Override manipulation of globals by nested matchers
-			if ( outermost ) {
-				dirruns = dirrunsUnique;
-				outermostContext = contextBackup;
-			}
-
-			return unmatched;
-		};
-
-	return bySet ?
-		markFunction( superMatcher ) :
-		superMatcher;
-}
-
-compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
-	var i,
-		setMatchers = [],
-		elementMatchers = [],
-		cached = compilerCache[ selector + " " ];
-
-	if ( !cached ) {
-		// Generate a function of recursive functions that can be used to check each element
-		if ( !match ) {
-			match = tokenize( selector );
-		}
-		i = match.length;
-		while ( i-- ) {
-			cached = matcherFromTokens( match[i] );
-			if ( cached[ expando ] ) {
-				setMatchers.push( cached );
-			} else {
-				elementMatchers.push( cached );
-			}
-		}
-
-		// Cache the compiled function
-		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
-
-		// Save selector and tokenization
-		cached.selector = selector;
-	}
-	return cached;
-};
-
-/**
- * A low-level selection function that works with Sizzle's compiled
- *  selector functions
- * @param {String|Function} selector A selector or a pre-compiled
- *  selector function built with Sizzle.compile
- * @param {Element} context
- * @param {Array} [results]
- * @param {Array} [seed] A set of elements to match against
- */
-select = Sizzle.select = function( selector, context, results, seed ) {
-	var i, tokens, token, type, find,
-		compiled = typeof selector === "function" && selector,
-		match = !seed && tokenize( (selector = compiled.selector || selector) );
-
-	results = results || [];
-
-	// Try to minimize operations if there is only one selector in the list and no seed
-	// (the latter of which guarantees us context)
-	if ( match.length === 1 ) {
-
-		// Reduce context if the leading compound selector is an ID
-		tokens = match[0] = match[0].slice( 0 );
-		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
-				context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {
-
-			context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
-			if ( !context ) {
-				return results;
-
-			// Precompiled matchers will still verify ancestry, so step up a level
-			} else if ( compiled ) {
-				context = context.parentNode;
-			}
-
-			selector = selector.slice( tokens.shift().value.length );
-		}
-
-		// Fetch a seed set for right-to-left matching
-		i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
-		while ( i-- ) {
-			token = tokens[i];
-
-			// Abort if we hit a combinator
-			if ( Expr.relative[ (type = token.type) ] ) {
-				break;
-			}
-			if ( (find = Expr.find[ type ]) ) {
-				// Search, expanding context for leading sibling combinators
-				if ( (seed = find(
-					token.matches[0].replace( runescape, funescape ),
-					rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
-				)) ) {
-
-					// If seed is empty or no tokens remain, we can return early
-					tokens.splice( i, 1 );
-					selector = seed.length && toSelector( tokens );
-					if ( !selector ) {
-						push.apply( results, seed );
-						return results;
-					}
-
-					break;
-				}
-			}
-		}
-	}
-
-	// Compile and execute a filtering function if one is not provided
-	// Provide `match` to avoid retokenization if we modified the selector above
-	( compiled || compile( selector, match ) )(
-		seed,
-		context,
-		!documentIsHTML,
-		results,
-		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
-	);
-	return results;
-};
-
-// One-time assignments
-
-// Sort stability
-support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
-
-// Support: Chrome 14-35+
-// Always assume duplicates if they aren't passed to the comparison function
-support.detectDuplicates = !!hasDuplicate;
-
-// Initialize against the default document
-setDocument();
-
-// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
-// Detached nodes confoundingly follow *each other*
-support.sortDetached = assert(function( el ) {
-	// Should return 1, but returns 4 (following)
-	return el.compareDocumentPosition( document.createElement("fieldset") ) & 1;
-});
-
-// Support: IE<8
-// Prevent attribute/property "interpolation"
-// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
-if ( !assert(function( el ) {
-	el.innerHTML = "";
-	return el.firstChild.getAttribute("href") === "#" ;
-}) ) {
-	addHandle( "type|href|height|width", function( elem, name, isXML ) {
-		if ( !isXML ) {
-			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
-		}
-	});
-}
-
-// Support: IE<9
-// Use defaultValue in place of getAttribute("value")
-if ( !support.attributes || !assert(function( el ) {
-	el.innerHTML = "";
-	el.firstChild.setAttribute( "value", "" );
-	return el.firstChild.getAttribute( "value" ) === "";
-}) ) {
-	addHandle( "value", function( elem, name, isXML ) {
-		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
-			return elem.defaultValue;
-		}
-	});
-}
-
-// Support: IE<9
-// Use getAttributeNode to fetch booleans when getAttribute lies
-if ( !assert(function( el ) {
-	return el.getAttribute("disabled") == null;
-}) ) {
-	addHandle( booleans, function( elem, name, isXML ) {
-		var val;
-		if ( !isXML ) {
-			return elem[ name ] === true ? name.toLowerCase() :
-					(val = elem.getAttributeNode( name )) && val.specified ?
-					val.value :
-				null;
-		}
-	});
-}
-
-return Sizzle;
-
-})( window );
-
-
-
-jQuery.find = Sizzle;
-jQuery.expr = Sizzle.selectors;
-
-// Deprecated
-jQuery.expr[ ":" ] = jQuery.expr.pseudos;
-jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
-jQuery.text = Sizzle.getText;
-jQuery.isXMLDoc = Sizzle.isXML;
-jQuery.contains = Sizzle.contains;
-jQuery.escapeSelector = Sizzle.escape;
-
-
-
-
-var dir = function( elem, dir, until ) {
-	var matched = [],
-		truncate = until !== undefined;
-
-	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
-		if ( elem.nodeType === 1 ) {
-			if ( truncate && jQuery( elem ).is( until ) ) {
-				break;
-			}
-			matched.push( elem );
-		}
-	}
-	return matched;
-};
-
-
-var siblings = function( n, elem ) {
-	var matched = [];
-
-	for ( ; n; n = n.nextSibling ) {
-		if ( n.nodeType === 1 && n !== elem ) {
-			matched.push( n );
-		}
-	}
-
-	return matched;
-};
-
-
-var rneedsContext = jQuery.expr.match.needsContext;
-
-var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
-
-
-
-var risSimple = /^.[^:#\[\.,]*$/;
-
-// Implement the identical functionality for filter and not
-function winnow( elements, qualifier, not ) {
-	if ( jQuery.isFunction( qualifier ) ) {
-		return jQuery.grep( elements, function( elem, i ) {
-			return !!qualifier.call( elem, i, elem ) !== not;
-		} );
-	}
-
-	// Single element
-	if ( qualifier.nodeType ) {
-		return jQuery.grep( elements, function( elem ) {
-			return ( elem === qualifier ) !== not;
-		} );
-	}
-
-	// Arraylike of elements (jQuery, arguments, Array)
-	if ( typeof qualifier !== "string" ) {
-		return jQuery.grep( elements, function( elem ) {
-			return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
-		} );
-	}
-
-	// Simple selector that can be filtered directly, removing non-Elements
-	if ( risSimple.test( qualifier ) ) {
-		return jQuery.filter( qualifier, elements, not );
-	}
-
-	// Complex selector, compare the two sets, removing non-Elements
-	qualifier = jQuery.filter( qualifier, elements );
-	return jQuery.grep( elements, function( elem ) {
-		return ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1;
-	} );
-}
-
-jQuery.filter = function( expr, elems, not ) {
-	var elem = elems[ 0 ];
-
-	if ( not ) {
-		expr = ":not(" + expr + ")";
-	}
-
-	if ( elems.length === 1 && elem.nodeType === 1 ) {
-		return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
-	}
-
-	return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
-		return elem.nodeType === 1;
-	} ) );
-};
-
-jQuery.fn.extend( {
-	find: function( selector ) {
-		var i, ret,
-			len = this.length,
-			self = this;
-
-		if ( typeof selector !== "string" ) {
-			return this.pushStack( jQuery( selector ).filter( function() {
-				for ( i = 0; i < len; i++ ) {
-					if ( jQuery.contains( self[ i ], this ) ) {
-						return true;
-					}
-				}
-			} ) );
-		}
-
-		ret = this.pushStack( [] );
-
-		for ( i = 0; i < len; i++ ) {
-			jQuery.find( selector, self[ i ], ret );
-		}
-
-		return len > 1 ? jQuery.uniqueSort( ret ) : ret;
-	},
-	filter: function( selector ) {
-		return this.pushStack( winnow( this, selector || [], false ) );
-	},
-	not: function( selector ) {
-		return this.pushStack( winnow( this, selector || [], true ) );
-	},
-	is: function( selector ) {
-		return !!winnow(
-			this,
-
-			// If this is a positional/relative selector, check membership in the returned set
-			// so $("p:first").is("p:last") won't return true for a doc with two "p".
-			typeof selector === "string" && rneedsContext.test( selector ) ?
-				jQuery( selector ) :
-				selector || [],
-			false
-		).length;
-	}
-} );
-
-
-// Initialize a jQuery object
-
-
-// A central reference to the root jQuery(document)
-var rootjQuery,
-
-	// A simple way to check for HTML strings
-	// Prioritize #id over  to avoid XSS via location.hash (#9521)
-	// Strict HTML recognition (#11290: must start with <)
-	// Shortcut simple #id case for speed
-	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
-
-	init = jQuery.fn.init = function( selector, context, root ) {
-		var match, elem;
-
-		// HANDLE: $(""), $(null), $(undefined), $(false)
-		if ( !selector ) {
-			return this;
-		}
-
-		// Method init() accepts an alternate rootjQuery
-		// so migrate can support jQuery.sub (gh-2101)
-		root = root || rootjQuery;
-
-		// Handle HTML strings
-		if ( typeof selector === "string" ) {
-			if ( selector[ 0 ] === "<" &&
-				selector[ selector.length - 1 ] === ">" &&
-				selector.length >= 3 ) {
-
-				// Assume that strings that start and end with <> are HTML and skip the regex check
-				match = [ null, selector, null ];
-
-			} else {
-				match = rquickExpr.exec( selector );
-			}
-
-			// Match html or make sure no context is specified for #id
-			if ( match && ( match[ 1 ] || !context ) ) {
-
-				// HANDLE: $(html) -> $(array)
-				if ( match[ 1 ] ) {
-					context = context instanceof jQuery ? context[ 0 ] : context;
-
-					// Option to run scripts is true for back-compat
-					// Intentionally let the error be thrown if parseHTML is not present
-					jQuery.merge( this, jQuery.parseHTML(
-						match[ 1 ],
-						context && context.nodeType ? context.ownerDocument || context : document,
-						true
-					) );
-
-					// HANDLE: $(html, props)
-					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
-						for ( match in context ) {
-
-							// Properties of context are called as methods if possible
-							if ( jQuery.isFunction( this[ match ] ) ) {
-								this[ match ]( context[ match ] );
-
-							// ...and otherwise set as attributes
-							} else {
-								this.attr( match, context[ match ] );
-							}
-						}
-					}
-
-					return this;
-
-				// HANDLE: $(#id)
-				} else {
-					elem = document.getElementById( match[ 2 ] );
-
-					if ( elem ) {
-
-						// Inject the element directly into the jQuery object
-						this[ 0 ] = elem;
-						this.length = 1;
-					}
-					return this;
-				}
-
-			// HANDLE: $(expr, $(...))
-			} else if ( !context || context.jquery ) {
-				return ( context || root ).find( selector );
-
-			// HANDLE: $(expr, context)
-			// (which is just equivalent to: $(context).find(expr)
-			} else {
-				return this.constructor( context ).find( selector );
-			}
-
-		// HANDLE: $(DOMElement)
-		} else if ( selector.nodeType ) {
-			this[ 0 ] = selector;
-			this.length = 1;
-			return this;
-
-		// HANDLE: $(function)
-		// Shortcut for document ready
-		} else if ( jQuery.isFunction( selector ) ) {
-			return root.ready !== undefined ?
-				root.ready( selector ) :
-
-				// Execute immediately if ready is not present
-				selector( jQuery );
-		}
-
-		return jQuery.makeArray( selector, this );
-	};
-
-// Give the init function the jQuery prototype for later instantiation
-init.prototype = jQuery.fn;
-
-// Initialize central reference
-rootjQuery = jQuery( document );
-
-
-var rparentsprev = /^(?:parents|prev(?:Until|All))/,
-
-	// Methods guaranteed to produce a unique set when starting from a unique set
-	guaranteedUnique = {
-		children: true,
-		contents: true,
-		next: true,
-		prev: true
-	};
-
-jQuery.fn.extend( {
-	has: function( target ) {
-		var targets = jQuery( target, this ),
-			l = targets.length;
-
-		return this.filter( function() {
-			var i = 0;
-			for ( ; i < l; i++ ) {
-				if ( jQuery.contains( this, targets[ i ] ) ) {
-					return true;
-				}
-			}
-		} );
-	},
-
-	closest: function( selectors, context ) {
-		var cur,
-			i = 0,
-			l = this.length,
-			matched = [],
-			targets = typeof selectors !== "string" && jQuery( selectors );
-
-		// Positional selectors never match, since there's no _selection_ context
-		if ( !rneedsContext.test( selectors ) ) {
-			for ( ; i < l; i++ ) {
-				for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
-
-					// Always skip document fragments
-					if ( cur.nodeType < 11 && ( targets ?
-						targets.index( cur ) > -1 :
-
-						// Don't pass non-elements to Sizzle
-						cur.nodeType === 1 &&
-							jQuery.find.matchesSelector( cur, selectors ) ) ) {
-
-						matched.push( cur );
-						break;
-					}
-				}
-			}
-		}
-
-		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
-	},
-
-	// Determine the position of an element within the set
-	index: function( elem ) {
-
-		// No argument, return index in parent
-		if ( !elem ) {
-			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
-		}
-
-		// Index in selector
-		if ( typeof elem === "string" ) {
-			return indexOf.call( jQuery( elem ), this[ 0 ] );
-		}
-
-		// Locate the position of the desired element
-		return indexOf.call( this,
-
-			// If it receives a jQuery object, the first element is used
-			elem.jquery ? elem[ 0 ] : elem
-		);
-	},
-
-	add: function( selector, context ) {
-		return this.pushStack(
-			jQuery.uniqueSort(
-				jQuery.merge( this.get(), jQuery( selector, context ) )
-			)
-		);
-	},
-
-	addBack: function( selector ) {
-		return this.add( selector == null ?
-			this.prevObject : this.prevObject.filter( selector )
-		);
-	}
-} );
-
-function sibling( cur, dir ) {
-	while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
-	return cur;
-}
-
-jQuery.each( {
-	parent: function( elem ) {
-		var parent = elem.parentNode;
-		return parent && parent.nodeType !== 11 ? parent : null;
-	},
-	parents: function( elem ) {
-		return dir( elem, "parentNode" );
-	},
-	parentsUntil: function( elem, i, until ) {
-		return dir( elem, "parentNode", until );
-	},
-	next: function( elem ) {
-		return sibling( elem, "nextSibling" );
-	},
-	prev: function( elem ) {
-		return sibling( elem, "previousSibling" );
-	},
-	nextAll: function( elem ) {
-		return dir( elem, "nextSibling" );
-	},
-	prevAll: function( elem ) {
-		return dir( elem, "previousSibling" );
-	},
-	nextUntil: function( elem, i, until ) {
-		return dir( elem, "nextSibling", until );
-	},
-	prevUntil: function( elem, i, until ) {
-		return dir( elem, "previousSibling", until );
-	},
-	siblings: function( elem ) {
-		return siblings( ( elem.parentNode || {} ).firstChild, elem );
-	},
-	children: function( elem ) {
-		return siblings( elem.firstChild );
-	},
-	contents: function( elem ) {
-		return elem.contentDocument || jQuery.merge( [], elem.childNodes );
-	}
-}, function( name, fn ) {
-	jQuery.fn[ name ] = function( until, selector ) {
-		var matched = jQuery.map( this, fn, until );
-
-		if ( name.slice( -5 ) !== "Until" ) {
-			selector = until;
-		}
-
-		if ( selector && typeof selector === "string" ) {
-			matched = jQuery.filter( selector, matched );
-		}
-
-		if ( this.length > 1 ) {
-
-			// Remove duplicates
-			if ( !guaranteedUnique[ name ] ) {
-				jQuery.uniqueSort( matched );
-			}
-
-			// Reverse order for parents* and prev-derivatives
-			if ( rparentsprev.test( name ) ) {
-				matched.reverse();
-			}
-		}
-
-		return this.pushStack( matched );
-	};
-} );
-var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
-
-
-
-// Convert String-formatted options into Object-formatted ones
-function createOptions( options ) {
-	var object = {};
-	jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
-		object[ flag ] = true;
-	} );
-	return object;
-}
-
-/*
- * Create a callback list using the following parameters:
- *
- *	options: an optional list of space-separated options that will change how
- *			the callback list behaves or a more traditional option object
- *
- * By default a callback list will act like an event callback list and can be
- * "fired" multiple times.
- *
- * Possible options:
- *
- *	once:			will ensure the callback list can only be fired once (like a Deferred)
- *
- *	memory:			will keep track of previous values and will call any callback added
- *					after the list has been fired right away with the latest "memorized"
- *					values (like a Deferred)
- *
- *	unique:			will ensure a callback can only be added once (no duplicate in the list)
- *
- *	stopOnFalse:	interrupt callings when a callback returns false
- *
- */
-jQuery.Callbacks = function( options ) {
-
-	// Convert options from String-formatted to Object-formatted if needed
-	// (we check in cache first)
-	options = typeof options === "string" ?
-		createOptions( options ) :
-		jQuery.extend( {}, options );
-
-	var // Flag to know if list is currently firing
-		firing,
-
-		// Last fire value for non-forgettable lists
-		memory,
-
-		// Flag to know if list was already fired
-		fired,
-
-		// Flag to prevent firing
-		locked,
-
-		// Actual callback list
-		list = [],
-
-		// Queue of execution data for repeatable lists
-		queue = [],
-
-		// Index of currently firing callback (modified by add/remove as needed)
-		firingIndex = -1,
-
-		// Fire callbacks
-		fire = function() {
-
-			// Enforce single-firing
-			locked = options.once;
-
-			// Execute callbacks for all pending executions,
-			// respecting firingIndex overrides and runtime changes
-			fired = firing = true;
-			for ( ; queue.length; firingIndex = -1 ) {
-				memory = queue.shift();
-				while ( ++firingIndex < list.length ) {
-
-					// Run callback and check for early termination
-					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
-						options.stopOnFalse ) {
-
-						// Jump to end and forget the data so .add doesn't re-fire
-						firingIndex = list.length;
-						memory = false;
-					}
-				}
-			}
-
-			// Forget the data if we're done with it
-			if ( !options.memory ) {
-				memory = false;
-			}
-
-			firing = false;
-
-			// Clean up if we're done firing for good
-			if ( locked ) {
-
-				// Keep an empty list if we have data for future add calls
-				if ( memory ) {
-					list = [];
-
-				// Otherwise, this object is spent
-				} else {
-					list = "";
-				}
-			}
-		},
-
-		// Actual Callbacks object
-		self = {
-
-			// Add a callback or a collection of callbacks to the list
-			add: function() {
-				if ( list ) {
-
-					// If we have memory from a past run, we should fire after adding
-					if ( memory && !firing ) {
-						firingIndex = list.length - 1;
-						queue.push( memory );
-					}
-
-					( function add( args ) {
-						jQuery.each( args, function( _, arg ) {
-							if ( jQuery.isFunction( arg ) ) {
-								if ( !options.unique || !self.has( arg ) ) {
-									list.push( arg );
-								}
-							} else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
-
-								// Inspect recursively
-								add( arg );
-							}
-						} );
-					} )( arguments );
-
-					if ( memory && !firing ) {
-						fire();
-					}
-				}
-				return this;
-			},
-
-			// Remove a callback from the list
-			remove: function() {
-				jQuery.each( arguments, function( _, arg ) {
-					var index;
-					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
-						list.splice( index, 1 );
-
-						// Handle firing indexes
-						if ( index <= firingIndex ) {
-							firingIndex--;
-						}
-					}
-				} );
-				return this;
-			},
-
-			// Check if a given callback is in the list.
-			// If no argument is given, return whether or not list has callbacks attached.
-			has: function( fn ) {
-				return fn ?
-					jQuery.inArray( fn, list ) > -1 :
-					list.length > 0;
-			},
-
-			// Remove all callbacks from the list
-			empty: function() {
-				if ( list ) {
-					list = [];
-				}
-				return this;
-			},
-
-			// Disable .fire and .add
-			// Abort any current/pending executions
-			// Clear all callbacks and values
-			disable: function() {
-				locked = queue = [];
-				list = memory = "";
-				return this;
-			},
-			disabled: function() {
-				return !list;
-			},
-
-			// Disable .fire
-			// Also disable .add unless we have memory (since it would have no effect)
-			// Abort any pending executions
-			lock: function() {
-				locked = queue = [];
-				if ( !memory && !firing ) {
-					list = memory = "";
-				}
-				return this;
-			},
-			locked: function() {
-				return !!locked;
-			},
-
-			// Call all callbacks with the given context and arguments
-			fireWith: function( context, args ) {
-				if ( !locked ) {
-					args = args || [];
-					args = [ context, args.slice ? args.slice() : args ];
-					queue.push( args );
-					if ( !firing ) {
-						fire();
-					}
-				}
-				return this;
-			},
-
-			// Call all the callbacks with the given arguments
-			fire: function() {
-				self.fireWith( this, arguments );
-				return this;
-			},
-
-			// To know if the callbacks have already been called at least once
-			fired: function() {
-				return !!fired;
-			}
-		};
-
-	return self;
-};
-
-
-function Identity( v ) {
-	return v;
-}
-function Thrower( ex ) {
-	throw ex;
-}
-
-function adoptValue( value, resolve, reject ) {
-	var method;
-
-	try {
-
-		// Check for promise aspect first to privilege synchronous behavior
-		if ( value && jQuery.isFunction( ( method = value.promise ) ) ) {
-			method.call( value ).done( resolve ).fail( reject );
-
-		// Other thenables
-		} else if ( value && jQuery.isFunction( ( method = value.then ) ) ) {
-			method.call( value, resolve, reject );
-
-		// Other non-thenables
-		} else {
-
-			// Support: Android 4.0 only
-			// Strict mode functions invoked without .call/.apply get global-object context
-			resolve.call( undefined, value );
-		}
-
-	// For Promises/A+, convert exceptions into rejections
-	// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
-	// Deferred#then to conditionally suppress rejection.
-	} catch ( value ) {
-
-		// Support: Android 4.0 only
-		// Strict mode functions invoked without .call/.apply get global-object context
-		reject.call( undefined, value );
-	}
-}
-
-jQuery.extend( {
-
-	Deferred: function( func ) {
-		var tuples = [
-
-				// action, add listener, callbacks,
-				// ... .then handlers, argument index, [final state]
-				[ "notify", "progress", jQuery.Callbacks( "memory" ),
-					jQuery.Callbacks( "memory" ), 2 ],
-				[ "resolve", "done", jQuery.Callbacks( "once memory" ),
-					jQuery.Callbacks( "once memory" ), 0, "resolved" ],
-				[ "reject", "fail", jQuery.Callbacks( "once memory" ),
-					jQuery.Callbacks( "once memory" ), 1, "rejected" ]
-			],
-			state = "pending",
-			promise = {
-				state: function() {
-					return state;
-				},
-				always: function() {
-					deferred.done( arguments ).fail( arguments );
-					return this;
-				},
-				"catch": function( fn ) {
-					return promise.then( null, fn );
-				},
-
-				// Keep pipe for back-compat
-				pipe: function( /* fnDone, fnFail, fnProgress */ ) {
-					var fns = arguments;
-
-					return jQuery.Deferred( function( newDefer ) {
-						jQuery.each( tuples, function( i, tuple ) {
-
-							// Map tuples (progress, done, fail) to arguments (done, fail, progress)
-							var fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
-
-							// deferred.progress(function() { bind to newDefer or newDefer.notify })
-							// deferred.done(function() { bind to newDefer or newDefer.resolve })
-							// deferred.fail(function() { bind to newDefer or newDefer.reject })
-							deferred[ tuple[ 1 ] ]( function() {
-								var returned = fn && fn.apply( this, arguments );
-								if ( returned && jQuery.isFunction( returned.promise ) ) {
-									returned.promise()
-										.progress( newDefer.notify )
-										.done( newDefer.resolve )
-										.fail( newDefer.reject );
-								} else {
-									newDefer[ tuple[ 0 ] + "With" ](
-										this,
-										fn ? [ returned ] : arguments
-									);
-								}
-							} );
-						} );
-						fns = null;
-					} ).promise();
-				},
-				then: function( onFulfilled, onRejected, onProgress ) {
-					var maxDepth = 0;
-					function resolve( depth, deferred, handler, special ) {
-						return function() {
-							var that = this,
-								args = arguments,
-								mightThrow = function() {
-									var returned, then;
-
-									// Support: Promises/A+ section 2.3.3.3.3
-									// https://promisesaplus.com/#point-59
-									// Ignore double-resolution attempts
-									if ( depth < maxDepth ) {
-										return;
-									}
-
-									returned = handler.apply( that, args );
-
-									// Support: Promises/A+ section 2.3.1
-									// https://promisesaplus.com/#point-48
-									if ( returned === deferred.promise() ) {
-										throw new TypeError( "Thenable self-resolution" );
-									}
-
-									// Support: Promises/A+ sections 2.3.3.1, 3.5
-									// https://promisesaplus.com/#point-54
-									// https://promisesaplus.com/#point-75
-									// Retrieve `then` only once
-									then = returned &&
-
-										// Support: Promises/A+ section 2.3.4
-										// https://promisesaplus.com/#point-64
-										// Only check objects and functions for thenability
-										( typeof returned === "object" ||
-											typeof returned === "function" ) &&
-										returned.then;
-
-									// Handle a returned thenable
-									if ( jQuery.isFunction( then ) ) {
-
-										// Special processors (notify) just wait for resolution
-										if ( special ) {
-											then.call(
-												returned,
-												resolve( maxDepth, deferred, Identity, special ),
-												resolve( maxDepth, deferred, Thrower, special )
-											);
-
-										// Normal processors (resolve) also hook into progress
-										} else {
-
-											// ...and disregard older resolution values
-											maxDepth++;
-
-											then.call(
-												returned,
-												resolve( maxDepth, deferred, Identity, special ),
-												resolve( maxDepth, deferred, Thrower, special ),
-												resolve( maxDepth, deferred, Identity,
-													deferred.notifyWith )
-											);
-										}
-
-									// Handle all other returned values
-									} else {
-
-										// Only substitute handlers pass on context
-										// and multiple values (non-spec behavior)
-										if ( handler !== Identity ) {
-											that = undefined;
-											args = [ returned ];
-										}
-
-										// Process the value(s)
-										// Default process is resolve
-										( special || deferred.resolveWith )( that, args );
-									}
-								},
-
-								// Only normal processors (resolve) catch and reject exceptions
-								process = special ?
-									mightThrow :
-									function() {
-										try {
-											mightThrow();
-										} catch ( e ) {
-
-											if ( jQuery.Deferred.exceptionHook ) {
-												jQuery.Deferred.exceptionHook( e,
-													process.stackTrace );
-											}
-
-											// Support: Promises/A+ section 2.3.3.3.4.1
-											// https://promisesaplus.com/#point-61
-											// Ignore post-resolution exceptions
-											if ( depth + 1 >= maxDepth ) {
-
-												// Only substitute handlers pass on context
-												// and multiple values (non-spec behavior)
-												if ( handler !== Thrower ) {
-													that = undefined;
-													args = [ e ];
-												}
-
-												deferred.rejectWith( that, args );
-											}
-										}
-									};
-
-							// Support: Promises/A+ section 2.3.3.3.1
-							// https://promisesaplus.com/#point-57
-							// Re-resolve promises immediately to dodge false rejection from
-							// subsequent errors
-							if ( depth ) {
-								process();
-							} else {
-
-								// Call an optional hook to record the stack, in case of exception
-								// since it's otherwise lost when execution goes async
-								if ( jQuery.Deferred.getStackHook ) {
-									process.stackTrace = jQuery.Deferred.getStackHook();
-								}
-								window.setTimeout( process );
-							}
-						};
-					}
-
-					return jQuery.Deferred( function( newDefer ) {
-
-						// progress_handlers.add( ... )
-						tuples[ 0 ][ 3 ].add(
-							resolve(
-								0,
-								newDefer,
-								jQuery.isFunction( onProgress ) ?
-									onProgress :
-									Identity,
-								newDefer.notifyWith
-							)
-						);
-
-						// fulfilled_handlers.add( ... )
-						tuples[ 1 ][ 3 ].add(
-							resolve(
-								0,
-								newDefer,
-								jQuery.isFunction( onFulfilled ) ?
-									onFulfilled :
-									Identity
-							)
-						);
-
-						// rejected_handlers.add( ... )
-						tuples[ 2 ][ 3 ].add(
-							resolve(
-								0,
-								newDefer,
-								jQuery.isFunction( onRejected ) ?
-									onRejected :
-									Thrower
-							)
-						);
-					} ).promise();
-				},
-
-				// Get a promise for this deferred
-				// If obj is provided, the promise aspect is added to the object
-				promise: function( obj ) {
-					return obj != null ? jQuery.extend( obj, promise ) : promise;
-				}
-			},
-			deferred = {};
-
-		// Add list-specific methods
-		jQuery.each( tuples, function( i, tuple ) {
-			var list = tuple[ 2 ],
-				stateString = tuple[ 5 ];
-
-			// promise.progress = list.add
-			// promise.done = list.add
-			// promise.fail = list.add
-			promise[ tuple[ 1 ] ] = list.add;
-
-			// Handle state
-			if ( stateString ) {
-				list.add(
-					function() {
-
-						// state = "resolved" (i.e., fulfilled)
-						// state = "rejected"
-						state = stateString;
-					},
-
-					// rejected_callbacks.disable
-					// fulfilled_callbacks.disable
-					tuples[ 3 - i ][ 2 ].disable,
-
-					// progress_callbacks.lock
-					tuples[ 0 ][ 2 ].lock
-				);
-			}
-
-			// progress_handlers.fire
-			// fulfilled_handlers.fire
-			// rejected_handlers.fire
-			list.add( tuple[ 3 ].fire );
-
-			// deferred.notify = function() { deferred.notifyWith(...) }
-			// deferred.resolve = function() { deferred.resolveWith(...) }
-			// deferred.reject = function() { deferred.rejectWith(...) }
-			deferred[ tuple[ 0 ] ] = function() {
-				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
-				return this;
-			};
-
-			// deferred.notifyWith = list.fireWith
-			// deferred.resolveWith = list.fireWith
-			// deferred.rejectWith = list.fireWith
-			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
-		} );
-
-		// Make the deferred a promise
-		promise.promise( deferred );
-
-		// Call given func if any
-		if ( func ) {
-			func.call( deferred, deferred );
-		}
-
-		// All done!
-		return deferred;
-	},
-
-	// Deferred helper
-	when: function( singleValue ) {
-		var
-
-			// count of uncompleted subordinates
-			remaining = arguments.length,
-
-			// count of unprocessed arguments
-			i = remaining,
-
-			// subordinate fulfillment data
-			resolveContexts = Array( i ),
-			resolveValues = slice.call( arguments ),
-
-			// the master Deferred
-			master = jQuery.Deferred(),
-
-			// subordinate callback factory
-			updateFunc = function( i ) {
-				return function( value ) {
-					resolveContexts[ i ] = this;
-					resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
-					if ( !( --remaining ) ) {
-						master.resolveWith( resolveContexts, resolveValues );
-					}
-				};
-			};
-
-		// Single- and empty arguments are adopted like Promise.resolve
-		if ( remaining <= 1 ) {
-			adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject );
-
-			// Use .then() to unwrap secondary thenables (cf. gh-3000)
-			if ( master.state() === "pending" ||
-				jQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
-
-				return master.then();
-			}
-		}
-
-		// Multiple arguments are aggregated like Promise.all array elements
-		while ( i-- ) {
-			adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
-		}
-
-		return master.promise();
-	}
-} );
-
-
-// These usually indicate a programmer mistake during development,
-// warn about them ASAP rather than swallowing them by default.
-var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
-
-jQuery.Deferred.exceptionHook = function( error, stack ) {
-
-	// Support: IE 8 - 9 only
-	// Console exists when dev tools are open, which can happen at any time
-	if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
-		window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
-	}
-};
-
-
-
-
-jQuery.readyException = function( error ) {
-	window.setTimeout( function() {
-		throw error;
-	} );
-};
-
-
-
-
-// The deferred used on DOM ready
-var readyList = jQuery.Deferred();
-
-jQuery.fn.ready = function( fn ) {
-
-	readyList
-		.then( fn )
-
-		// Wrap jQuery.readyException in a function so that the lookup
-		// happens at the time of error handling instead of callback
-		// registration.
-		.catch( function( error ) {
-			jQuery.readyException( error );
-		} );
-
-	return this;
-};
-
-jQuery.extend( {
-
-	// Is the DOM ready to be used? Set to true once it occurs.
-	isReady: false,
-
-	// A counter to track how many items to wait for before
-	// the ready event fires. See #6781
-	readyWait: 1,
-
-	// Hold (or release) the ready event
-	holdReady: function( hold ) {
-		if ( hold ) {
-			jQuery.readyWait++;
-		} else {
-			jQuery.ready( true );
-		}
-	},
-
-	// Handle when the DOM is ready
-	ready: function( wait ) {
-
-		// Abort if there are pending holds or we're already ready
-		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
-			return;
-		}
-
-		// Remember that the DOM is ready
-		jQuery.isReady = true;
-
-		// If a normal DOM Ready event fired, decrement, and wait if need be
-		if ( wait !== true && --jQuery.readyWait > 0 ) {
-			return;
-		}
-
-		// If there are functions bound, to execute
-		readyList.resolveWith( document, [ jQuery ] );
-	}
-} );
-
-jQuery.ready.then = readyList.then;
-
-// The ready event handler and self cleanup method
-function completed() {
-	document.removeEventListener( "DOMContentLoaded", completed );
-	window.removeEventListener( "load", completed );
-	jQuery.ready();
-}
-
-// Catch cases where $(document).ready() is called
-// after the browser event has already occurred.
-// Support: IE <=9 - 10 only
-// Older IE sometimes signals "interactive" too soon
-if ( document.readyState === "complete" ||
-	( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
-
-	// Handle it asynchronously to allow scripts the opportunity to delay ready
-	window.setTimeout( jQuery.ready );
-
-} else {
-
-	// Use the handy event callback
-	document.addEventListener( "DOMContentLoaded", completed );
-
-	// A fallback to window.onload, that will always work
-	window.addEventListener( "load", completed );
-}
-
-
-
-
-// Multifunctional method to get and set values of a collection
-// The value/s can optionally be executed if it's a function
-var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
-	var i = 0,
-		len = elems.length,
-		bulk = key == null;
-
-	// Sets many values
-	if ( jQuery.type( key ) === "object" ) {
-		chainable = true;
-		for ( i in key ) {
-			access( elems, fn, i, key[ i ], true, emptyGet, raw );
-		}
-
-	// Sets one value
-	} else if ( value !== undefined ) {
-		chainable = true;
-
-		if ( !jQuery.isFunction( value ) ) {
-			raw = true;
-		}
-
-		if ( bulk ) {
-
-			// Bulk operations run against the entire set
-			if ( raw ) {
-				fn.call( elems, value );
-				fn = null;
-
-			// ...except when executing function values
-			} else {
-				bulk = fn;
-				fn = function( elem, key, value ) {
-					return bulk.call( jQuery( elem ), value );
-				};
-			}
-		}
-
-		if ( fn ) {
-			for ( ; i < len; i++ ) {
-				fn(
-					elems[ i ], key, raw ?
-					value :
-					value.call( elems[ i ], i, fn( elems[ i ], key ) )
-				);
-			}
-		}
-	}
-
-	if ( chainable ) {
-		return elems;
-	}
-
-	// Gets
-	if ( bulk ) {
-		return fn.call( elems );
-	}
-
-	return len ? fn( elems[ 0 ], key ) : emptyGet;
-};
-var acceptData = function( owner ) {
-
-	// Accepts only:
-	//  - Node
-	//    - Node.ELEMENT_NODE
-	//    - Node.DOCUMENT_NODE
-	//  - Object
-	//    - Any
-	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
-};
-
-
-
-
-function Data() {
-	this.expando = jQuery.expando + Data.uid++;
-}
-
-Data.uid = 1;
-
-Data.prototype = {
-
-	cache: function( owner ) {
-
-		// Check if the owner object already has a cache
-		var value = owner[ this.expando ];
-
-		// If not, create one
-		if ( !value ) {
-			value = {};
-
-			// We can accept data for non-element nodes in modern browsers,
-			// but we should not, see #8335.
-			// Always return an empty object.
-			if ( acceptData( owner ) ) {
-
-				// If it is a node unlikely to be stringify-ed or looped over
-				// use plain assignment
-				if ( owner.nodeType ) {
-					owner[ this.expando ] = value;
-
-				// Otherwise secure it in a non-enumerable property
-				// configurable must be true to allow the property to be
-				// deleted when data is removed
-				} else {
-					Object.defineProperty( owner, this.expando, {
-						value: value,
-						configurable: true
-					} );
-				}
-			}
-		}
-
-		return value;
-	},
-	set: function( owner, data, value ) {
-		var prop,
-			cache = this.cache( owner );
-
-		// Handle: [ owner, key, value ] args
-		// Always use camelCase key (gh-2257)
-		if ( typeof data === "string" ) {
-			cache[ jQuery.camelCase( data ) ] = value;
-
-		// Handle: [ owner, { properties } ] args
-		} else {
-
-			// Copy the properties one-by-one to the cache object
-			for ( prop in data ) {
-				cache[ jQuery.camelCase( prop ) ] = data[ prop ];
-			}
-		}
-		return cache;
-	},
-	get: function( owner, key ) {
-		return key === undefined ?
-			this.cache( owner ) :
-
-			// Always use camelCase key (gh-2257)
-			owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ];
-	},
-	access: function( owner, key, value ) {
-
-		// In cases where either:
-		//
-		//   1. No key was specified
-		//   2. A string key was specified, but no value provided
-		//
-		// Take the "read" path and allow the get method to determine
-		// which value to return, respectively either:
-		//
-		//   1. The entire cache object
-		//   2. The data stored at the key
-		//
-		if ( key === undefined ||
-				( ( key && typeof key === "string" ) && value === undefined ) ) {
-
-			return this.get( owner, key );
-		}
-
-		// When the key is not a string, or both a key and value
-		// are specified, set or extend (existing objects) with either:
-		//
-		//   1. An object of properties
-		//   2. A key and value
-		//
-		this.set( owner, key, value );
-
-		// Since the "set" path can have two possible entry points
-		// return the expected data based on which path was taken[*]
-		return value !== undefined ? value : key;
-	},
-	remove: function( owner, key ) {
-		var i,
-			cache = owner[ this.expando ];
-
-		if ( cache === undefined ) {
-			return;
-		}
-
-		if ( key !== undefined ) {
-
-			// Support array or space separated string of keys
-			if ( jQuery.isArray( key ) ) {
-
-				// If key is an array of keys...
-				// We always set camelCase keys, so remove that.
-				key = key.map( jQuery.camelCase );
-			} else {
-				key = jQuery.camelCase( key );
-
-				// If a key with the spaces exists, use it.
-				// Otherwise, create an array by matching non-whitespace
-				key = key in cache ?
-					[ key ] :
-					( key.match( rnothtmlwhite ) || [] );
-			}
-
-			i = key.length;
-
-			while ( i-- ) {
-				delete cache[ key[ i ] ];
-			}
-		}
-
-		// Remove the expando if there's no more data
-		if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
-
-			// Support: Chrome <=35 - 45
-			// Webkit & Blink performance suffers when deleting properties
-			// from DOM nodes, so set to undefined instead
-			// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
-			if ( owner.nodeType ) {
-				owner[ this.expando ] = undefined;
-			} else {
-				delete owner[ this.expando ];
-			}
-		}
-	},
-	hasData: function( owner ) {
-		var cache = owner[ this.expando ];
-		return cache !== undefined && !jQuery.isEmptyObject( cache );
-	}
-};
-var dataPriv = new Data();
-
-var dataUser = new Data();
-
-
-
-//	Implementation Summary
-//
-//	1. Enforce API surface and semantic compatibility with 1.9.x branch
-//	2. Improve the module's maintainability by reducing the storage
-//		paths to a single mechanism.
-//	3. Use the same single mechanism to support "private" and "user" data.
-//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
-//	5. Avoid exposing implementation details on user objects (eg. expando properties)
-//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
-
-var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
-	rmultiDash = /[A-Z]/g;
-
-function getData( data ) {
-	if ( data === "true" ) {
-		return true;
-	}
-
-	if ( data === "false" ) {
-		return false;
-	}
-
-	if ( data === "null" ) {
-		return null;
-	}
-
-	// Only convert to a number if it doesn't change the string
-	if ( data === +data + "" ) {
-		return +data;
-	}
-
-	if ( rbrace.test( data ) ) {
-		return JSON.parse( data );
-	}
-
-	return data;
-}
-
-function dataAttr( elem, key, data ) {
-	var name;
-
-	// If nothing was found internally, try to fetch any
-	// data from the HTML5 data-* attribute
-	if ( data === undefined && elem.nodeType === 1 ) {
-		name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
-		data = elem.getAttribute( name );
-
-		if ( typeof data === "string" ) {
-			try {
-				data = getData( data );
-			} catch ( e ) {}
-
-			// Make sure we set the data so it isn't changed later
-			dataUser.set( elem, key, data );
-		} else {
-			data = undefined;
-		}
-	}
-	return data;
-}
-
-jQuery.extend( {
-	hasData: function( elem ) {
-		return dataUser.hasData( elem ) || dataPriv.hasData( elem );
-	},
-
-	data: function( elem, name, data ) {
-		return dataUser.access( elem, name, data );
-	},
-
-	removeData: function( elem, name ) {
-		dataUser.remove( elem, name );
-	},
-
-	// TODO: Now that all calls to _data and _removeData have been replaced
-	// with direct calls to dataPriv methods, these can be deprecated.
-	_data: function( elem, name, data ) {
-		return dataPriv.access( elem, name, data );
-	},
-
-	_removeData: function( elem, name ) {
-		dataPriv.remove( elem, name );
-	}
-} );
-
-jQuery.fn.extend( {
-	data: function( key, value ) {
-		var i, name, data,
-			elem = this[ 0 ],
-			attrs = elem && elem.attributes;
-
-		// Gets all values
-		if ( key === undefined ) {
-			if ( this.length ) {
-				data = dataUser.get( elem );
-
-				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
-					i = attrs.length;
-					while ( i-- ) {
-
-						// Support: IE 11 only
-						// The attrs elements can be null (#14894)
-						if ( attrs[ i ] ) {
-							name = attrs[ i ].name;
-							if ( name.indexOf( "data-" ) === 0 ) {
-								name = jQuery.camelCase( name.slice( 5 ) );
-								dataAttr( elem, name, data[ name ] );
-							}
-						}
-					}
-					dataPriv.set( elem, "hasDataAttrs", true );
-				}
-			}
-
-			return data;
-		}
-
-		// Sets multiple values
-		if ( typeof key === "object" ) {
-			return this.each( function() {
-				dataUser.set( this, key );
-			} );
-		}
-
-		return access( this, function( value ) {
-			var data;
-
-			// The calling jQuery object (element matches) is not empty
-			// (and therefore has an element appears at this[ 0 ]) and the
-			// `value` parameter was not undefined. An empty jQuery object
-			// will result in `undefined` for elem = this[ 0 ] which will
-			// throw an exception if an attempt to read a data cache is made.
-			if ( elem && value === undefined ) {
-
-				// Attempt to get data from the cache
-				// The key will always be camelCased in Data
-				data = dataUser.get( elem, key );
-				if ( data !== undefined ) {
-					return data;
-				}
-
-				// Attempt to "discover" the data in
-				// HTML5 custom data-* attrs
-				data = dataAttr( elem, key );
-				if ( data !== undefined ) {
-					return data;
-				}
-
-				// We tried really hard, but the data doesn't exist.
-				return;
-			}
-
-			// Set the data...
-			this.each( function() {
-
-				// We always store the camelCased key
-				dataUser.set( this, key, value );
-			} );
-		}, null, value, arguments.length > 1, null, true );
-	},
-
-	removeData: function( key ) {
-		return this.each( function() {
-			dataUser.remove( this, key );
-		} );
-	}
-} );
-
-
-jQuery.extend( {
-	queue: function( elem, type, data ) {
-		var queue;
-
-		if ( elem ) {
-			type = ( type || "fx" ) + "queue";
-			queue = dataPriv.get( elem, type );
-
-			// Speed up dequeue by getting out quickly if this is just a lookup
-			if ( data ) {
-				if ( !queue || jQuery.isArray( data ) ) {
-					queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
-				} else {
-					queue.push( data );
-				}
-			}
-			return queue || [];
-		}
-	},
-
-	dequeue: function( elem, type ) {
-		type = type || "fx";
-
-		var queue = jQuery.queue( elem, type ),
-			startLength = queue.length,
-			fn = queue.shift(),
-			hooks = jQuery._queueHooks( elem, type ),
-			next = function() {
-				jQuery.dequeue( elem, type );
-			};
-
-		// If the fx queue is dequeued, always remove the progress sentinel
-		if ( fn === "inprogress" ) {
-			fn = queue.shift();
-			startLength--;
-		}
-
-		if ( fn ) {
-
-			// Add a progress sentinel to prevent the fx queue from being
-			// automatically dequeued
-			if ( type === "fx" ) {
-				queue.unshift( "inprogress" );
-			}
-
-			// Clear up the last queue stop function
-			delete hooks.stop;
-			fn.call( elem, next, hooks );
-		}
-
-		if ( !startLength && hooks ) {
-			hooks.empty.fire();
-		}
-	},
-
-	// Not public - generate a queueHooks object, or return the current one
-	_queueHooks: function( elem, type ) {
-		var key = type + "queueHooks";
-		return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
-			empty: jQuery.Callbacks( "once memory" ).add( function() {
-				dataPriv.remove( elem, [ type + "queue", key ] );
-			} )
-		} );
-	}
-} );
-
-jQuery.fn.extend( {
-	queue: function( type, data ) {
-		var setter = 2;
-
-		if ( typeof type !== "string" ) {
-			data = type;
-			type = "fx";
-			setter--;
-		}
-
-		if ( arguments.length < setter ) {
-			return jQuery.queue( this[ 0 ], type );
-		}
-
-		return data === undefined ?
-			this :
-			this.each( function() {
-				var queue = jQuery.queue( this, type, data );
-
-				// Ensure a hooks for this queue
-				jQuery._queueHooks( this, type );
-
-				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
-					jQuery.dequeue( this, type );
-				}
-			} );
-	},
-	dequeue: function( type ) {
-		return this.each( function() {
-			jQuery.dequeue( this, type );
-		} );
-	},
-	clearQueue: function( type ) {
-		return this.queue( type || "fx", [] );
-	},
-
-	// Get a promise resolved when queues of a certain type
-	// are emptied (fx is the type by default)
-	promise: function( type, obj ) {
-		var tmp,
-			count = 1,
-			defer = jQuery.Deferred(),
-			elements = this,
-			i = this.length,
-			resolve = function() {
-				if ( !( --count ) ) {
-					defer.resolveWith( elements, [ elements ] );
-				}
-			};
-
-		if ( typeof type !== "string" ) {
-			obj = type;
-			type = undefined;
-		}
-		type = type || "fx";
-
-		while ( i-- ) {
-			tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
-			if ( tmp && tmp.empty ) {
-				count++;
-				tmp.empty.add( resolve );
-			}
-		}
-		resolve();
-		return defer.promise( obj );
-	}
-} );
-var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
-
-var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
-
-
-var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
-
-var isHiddenWithinTree = function( elem, el ) {
-
-		// isHiddenWithinTree might be called from jQuery#filter function;
-		// in that case, element will be second argument
-		elem = el || elem;
-
-		// Inline style trumps all
-		return elem.style.display === "none" ||
-			elem.style.display === "" &&
-
-			// Otherwise, check computed style
-			// Support: Firefox <=43 - 45
-			// Disconnected elements can have computed display: none, so first confirm that elem is
-			// in the document.
-			jQuery.contains( elem.ownerDocument, elem ) &&
-
-			jQuery.css( elem, "display" ) === "none";
-	};
-
-var swap = function( elem, options, callback, args ) {
-	var ret, name,
-		old = {};
-
-	// Remember the old values, and insert the new ones
-	for ( name in options ) {
-		old[ name ] = elem.style[ name ];
-		elem.style[ name ] = options[ name ];
-	}
-
-	ret = callback.apply( elem, args || [] );
-
-	// Revert the old values
-	for ( name in options ) {
-		elem.style[ name ] = old[ name ];
-	}
-
-	return ret;
-};
-
-
-
-
-function adjustCSS( elem, prop, valueParts, tween ) {
-	var adjusted,
-		scale = 1,
-		maxIterations = 20,
-		currentValue = tween ?
-			function() {
-				return tween.cur();
-			} :
-			function() {
-				return jQuery.css( elem, prop, "" );
-			},
-		initial = currentValue(),
-		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
-
-		// Starting value computation is required for potential unit mismatches
-		initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
-			rcssNum.exec( jQuery.css( elem, prop ) );
-
-	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
-
-		// Trust units reported by jQuery.css
-		unit = unit || initialInUnit[ 3 ];
-
-		// Make sure we update the tween properties later on
-		valueParts = valueParts || [];
-
-		// Iteratively approximate from a nonzero starting point
-		initialInUnit = +initial || 1;
-
-		do {
-
-			// If previous iteration zeroed out, double until we get *something*.
-			// Use string for doubling so we don't accidentally see scale as unchanged below
-			scale = scale || ".5";
-
-			// Adjust and apply
-			initialInUnit = initialInUnit / scale;
-			jQuery.style( elem, prop, initialInUnit + unit );
-
-		// Update scale, tolerating zero or NaN from tween.cur()
-		// Break the loop if scale is unchanged or perfect, or if we've just had enough.
-		} while (
-			scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
-		);
-	}
-
-	if ( valueParts ) {
-		initialInUnit = +initialInUnit || +initial || 0;
-
-		// Apply relative offset (+=/-=) if specified
-		adjusted = valueParts[ 1 ] ?
-			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
-			+valueParts[ 2 ];
-		if ( tween ) {
-			tween.unit = unit;
-			tween.start = initialInUnit;
-			tween.end = adjusted;
-		}
-	}
-	return adjusted;
-}
-
-
-var defaultDisplayMap = {};
-
-function getDefaultDisplay( elem ) {
-	var temp,
-		doc = elem.ownerDocument,
-		nodeName = elem.nodeName,
-		display = defaultDisplayMap[ nodeName ];
-
-	if ( display ) {
-		return display;
-	}
-
-	temp = doc.body.appendChild( doc.createElement( nodeName ) );
-	display = jQuery.css( temp, "display" );
-
-	temp.parentNode.removeChild( temp );
-
-	if ( display === "none" ) {
-		display = "block";
-	}
-	defaultDisplayMap[ nodeName ] = display;
-
-	return display;
-}
-
-function showHide( elements, show ) {
-	var display, elem,
-		values = [],
-		index = 0,
-		length = elements.length;
-
-	// Determine new display value for elements that need to change
-	for ( ; index < length; index++ ) {
-		elem = elements[ index ];
-		if ( !elem.style ) {
-			continue;
-		}
-
-		display = elem.style.display;
-		if ( show ) {
-
-			// Since we force visibility upon cascade-hidden elements, an immediate (and slow)
-			// check is required in this first loop unless we have a nonempty display value (either
-			// inline or about-to-be-restored)
-			if ( display === "none" ) {
-				values[ index ] = dataPriv.get( elem, "display" ) || null;
-				if ( !values[ index ] ) {
-					elem.style.display = "";
-				}
-			}
-			if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
-				values[ index ] = getDefaultDisplay( elem );
-			}
-		} else {
-			if ( display !== "none" ) {
-				values[ index ] = "none";
-
-				// Remember what we're overwriting
-				dataPriv.set( elem, "display", display );
-			}
-		}
-	}
-
-	// Set the display of the elements in a second loop to avoid constant reflow
-	for ( index = 0; index < length; index++ ) {
-		if ( values[ index ] != null ) {
-			elements[ index ].style.display = values[ index ];
-		}
-	}
-
-	return elements;
-}
-
-jQuery.fn.extend( {
-	show: function() {
-		return showHide( this, true );
-	},
-	hide: function() {
-		return showHide( this );
-	},
-	toggle: function( state ) {
-		if ( typeof state === "boolean" ) {
-			return state ? this.show() : this.hide();
-		}
-
-		return this.each( function() {
-			if ( isHiddenWithinTree( this ) ) {
-				jQuery( this ).show();
-			} else {
-				jQuery( this ).hide();
-			}
-		} );
-	}
-} );
-var rcheckableType = ( /^(?:checkbox|radio)$/i );
-
-var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i );
-
-var rscriptType = ( /^$|\/(?:java|ecma)script/i );
-
-
-
-// We have to close these tags to support XHTML (#13200)
-var wrapMap = {
-
-	// Support: IE <=9 only
-	option: [ 1, "" ],
-
-	// XHTML parsers do not magically insert elements in the
-	// same way that tag soup parsers do. So we cannot shorten
-	// this by omitting  or other required elements.
-	thead: [ 1, "", "
" ], - col: [ 2, "", "
" ], - tr: [ 2, "", "
" ], - td: [ 3, "", "
" ], - - _default: [ 0, "", "" ] -}; - -// Support: IE <=9 only -wrapMap.optgroup = wrapMap.option; - -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - - -function getAll( context, tag ) { - - // Support: IE <=9 - 11 only - // Use typeof to avoid zero-argument method invocation on host objects (#15151) - var ret; - - if ( typeof context.getElementsByTagName !== "undefined" ) { - ret = context.getElementsByTagName( tag || "*" ); - - } else if ( typeof context.querySelectorAll !== "undefined" ) { - ret = context.querySelectorAll( tag || "*" ); - - } else { - ret = []; - } - - if ( tag === undefined || tag && jQuery.nodeName( context, tag ) ) { - return jQuery.merge( [ context ], ret ); - } - - return ret; -} - - -// Mark scripts as having already been evaluated -function setGlobalEval( elems, refElements ) { - var i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - dataPriv.set( - elems[ i ], - "globalEval", - !refElements || dataPriv.get( refElements[ i ], "globalEval" ) - ); - } -} - - -var rhtml = /<|&#?\w+;/; - -function buildFragment( elems, context, scripts, selection, ignored ) { - var elem, tmp, tag, wrap, contains, j, - fragment = context.createDocumentFragment(), - nodes = [], - i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - elem = elems[ i ]; - - if ( elem || elem === 0 ) { - - // Add nodes directly - if ( jQuery.type( elem ) === "object" ) { - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); - - // Convert non-html into a text node - } else if ( !rhtml.test( elem ) ) { - nodes.push( context.createTextNode( elem ) ); - - // Convert html into DOM nodes - } else { - tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); - - // Deserialize a standard representation - tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); - wrap = wrapMap[ tag ] || wrapMap._default; - tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; - - // Descend through wrappers to the right content - j = wrap[ 0 ]; - while ( j-- ) { - tmp = tmp.lastChild; - } - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( nodes, tmp.childNodes ); - - // Remember the top-level container - tmp = fragment.firstChild; - - // Ensure the created nodes are orphaned (#12392) - tmp.textContent = ""; - } - } - } - - // Remove wrapper from fragment - fragment.textContent = ""; - - i = 0; - while ( ( elem = nodes[ i++ ] ) ) { - - // Skip elements already in the context collection (trac-4087) - if ( selection && jQuery.inArray( elem, selection ) > -1 ) { - if ( ignored ) { - ignored.push( elem ); - } - continue; - } - - contains = jQuery.contains( elem.ownerDocument, elem ); - - // Append to fragment - tmp = getAll( fragment.appendChild( elem ), "script" ); - - // Preserve script evaluation history - if ( contains ) { - setGlobalEval( tmp ); - } - - // Capture executables - if ( scripts ) { - j = 0; - while ( ( elem = tmp[ j++ ] ) ) { - if ( rscriptType.test( elem.type || "" ) ) { - scripts.push( elem ); - } - } - } - } - - return fragment; -} - - -( function() { - var fragment = document.createDocumentFragment(), - div = fragment.appendChild( document.createElement( "div" ) ), - input = document.createElement( "input" ); - - // Support: Android 4.0 - 4.3 only - // Check state lost if the name is set (#11217) - // Support: Windows Web Apps (WWA) - // `name` and `type` must use .setAttribute for WWA (#14901) - input.setAttribute( "type", "radio" ); - input.setAttribute( "checked", "checked" ); - input.setAttribute( "name", "t" ); - - div.appendChild( input ); - - // Support: Android <=4.1 only - // Older WebKit doesn't clone checked state correctly in fragments - support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; - - // Support: IE <=11 only - // Make sure textarea (and checkbox) defaultValue is properly cloned - div.innerHTML = ""; - support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; -} )(); -var documentElement = document.documentElement; - - - -var - rkeyEvent = /^key/, - rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, - rtypenamespace = /^([^.]*)(?:\.(.+)|)/; - -function returnTrue() { - return true; -} - -function returnFalse() { - return false; -} - -// Support: IE <=9 only -// See #13393 for more info -function safeActiveElement() { - try { - return document.activeElement; - } catch ( err ) { } -} - -function on( elem, types, selector, data, fn, one ) { - var origFn, type; - - // Types can be a map of types/handlers - if ( typeof types === "object" ) { - - // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { - - // ( types-Object, data ) - data = data || selector; - selector = undefined; - } - for ( type in types ) { - on( elem, type, selector, data, types[ type ], one ); - } - return elem; - } - - if ( data == null && fn == null ) { - - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if ( fn == null ) { - if ( typeof selector === "string" ) { - - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if ( fn === false ) { - fn = returnFalse; - } else if ( !fn ) { - return elem; - } - - if ( one === 1 ) { - origFn = fn; - fn = function( event ) { - - // Can use an empty set, since event contains the info - jQuery().off( event ); - return origFn.apply( this, arguments ); - }; - - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); - } - return elem.each( function() { - jQuery.event.add( this, types, fn, data, selector ); - } ); -} - -/* - * Helper functions for managing events -- not part of the public interface. - * Props to Dean Edwards' addEvent library for many of the ideas. - */ -jQuery.event = { - - global: {}, - - add: function( elem, types, handler, data, selector ) { - - var handleObjIn, eventHandle, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = dataPriv.get( elem ); - - // Don't attach events to noData or text/comment nodes (but allow plain objects) - if ( !elemData ) { - return; - } - - // Caller can pass in an object of custom data in lieu of the handler - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - selector = handleObjIn.selector; - } - - // Ensure that invalid selectors throw exceptions at attach time - // Evaluate against documentElement in case elem is a non-element node (e.g., document) - if ( selector ) { - jQuery.find.matchesSelector( documentElement, selector ); - } - - // Make sure that the handler has a unique ID, used to find/remove it later - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure and main handler, if this is the first - if ( !( events = elemData.events ) ) { - events = elemData.events = {}; - } - if ( !( eventHandle = elemData.handle ) ) { - eventHandle = elemData.handle = function( e ) { - - // Discard the second event of a jQuery.event.trigger() and - // when an event is called after a page has unloaded - return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? - jQuery.event.dispatch.apply( elem, arguments ) : undefined; - }; - } - - // Handle multiple events separated by a space - types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[ t ] ) || []; - type = origType = tmp[ 1 ]; - namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); - - // There *must* be a type, no attaching namespace-only handlers - if ( !type ) { - continue; - } - - // If event changes its type, use the special event handlers for the changed type - special = jQuery.event.special[ type ] || {}; - - // If selector defined, determine special event api type, otherwise given type - type = ( selector ? special.delegateType : special.bindType ) || type; - - // Update special based on newly reset type - special = jQuery.event.special[ type ] || {}; - - // handleObj is passed to all event handlers - handleObj = jQuery.extend( { - type: type, - origType: origType, - data: data, - handler: handler, - guid: handler.guid, - selector: selector, - needsContext: selector && jQuery.expr.match.needsContext.test( selector ), - namespace: namespaces.join( "." ) - }, handleObjIn ); - - // Init the event handler queue if we're the first - if ( !( handlers = events[ type ] ) ) { - handlers = events[ type ] = []; - handlers.delegateCount = 0; - - // Only use addEventListener if the special events handler returns false - if ( !special.setup || - special.setup.call( elem, data, namespaces, eventHandle ) === false ) { - - if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle ); - } - } - } - - if ( special.add ) { - special.add.call( elem, handleObj ); - - if ( !handleObj.handler.guid ) { - handleObj.handler.guid = handler.guid; - } - } - - // Add to the element's handler list, delegates in front - if ( selector ) { - handlers.splice( handlers.delegateCount++, 0, handleObj ); - } else { - handlers.push( handleObj ); - } - - // Keep track of which events have ever been used, for event optimization - jQuery.event.global[ type ] = true; - } - - }, - - // Detach an event or set of events from an element - remove: function( elem, types, handler, selector, mappedTypes ) { - - var j, origCount, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); - - if ( !elemData || !( events = elemData.events ) ) { - return; - } - - // Once for each type.namespace in types; type may be omitted - types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[ t ] ) || []; - type = origType = tmp[ 1 ]; - namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); - - // Unbind all events (on this namespace, if provided) for the element - if ( !type ) { - for ( type in events ) { - jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); - } - continue; - } - - special = jQuery.event.special[ type ] || {}; - type = ( selector ? special.delegateType : special.bindType ) || type; - handlers = events[ type ] || []; - tmp = tmp[ 2 ] && - new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); - - // Remove matching events - origCount = j = handlers.length; - while ( j-- ) { - handleObj = handlers[ j ]; - - if ( ( mappedTypes || origType === handleObj.origType ) && - ( !handler || handler.guid === handleObj.guid ) && - ( !tmp || tmp.test( handleObj.namespace ) ) && - ( !selector || selector === handleObj.selector || - selector === "**" && handleObj.selector ) ) { - handlers.splice( j, 1 ); - - if ( handleObj.selector ) { - handlers.delegateCount--; - } - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } - } - - // Remove generic event handler if we removed something and no more handlers exist - // (avoids potential for endless recursion during removal of special event handlers) - if ( origCount && !handlers.length ) { - if ( !special.teardown || - special.teardown.call( elem, namespaces, elemData.handle ) === false ) { - - jQuery.removeEvent( elem, type, elemData.handle ); - } - - delete events[ type ]; - } - } - - // Remove data and the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - dataPriv.remove( elem, "handle events" ); - } - }, - - dispatch: function( nativeEvent ) { - - // Make a writable jQuery.Event from the native event object - var event = jQuery.event.fix( nativeEvent ); - - var i, j, ret, matched, handleObj, handlerQueue, - args = new Array( arguments.length ), - handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], - special = jQuery.event.special[ event.type ] || {}; - - // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[ 0 ] = event; - - for ( i = 1; i < arguments.length; i++ ) { - args[ i ] = arguments[ i ]; - } - - event.delegateTarget = this; - - // Call the preDispatch hook for the mapped type, and let it bail if desired - if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { - return; - } - - // Determine handlers - handlerQueue = jQuery.event.handlers.call( this, event, handlers ); - - // Run delegates first; they may want to stop propagation beneath us - i = 0; - while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { - event.currentTarget = matched.elem; - - j = 0; - while ( ( handleObj = matched.handlers[ j++ ] ) && - !event.isImmediatePropagationStopped() ) { - - // Triggered event must either 1) have no namespace, or 2) have namespace(s) - // a subset or equal to those in the bound event (both can have no namespace). - if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { - - event.handleObj = handleObj; - event.data = handleObj.data; - - ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || - handleObj.handler ).apply( matched.elem, args ); - - if ( ret !== undefined ) { - if ( ( event.result = ret ) === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - } - } - } - - // Call the postDispatch hook for the mapped type - if ( special.postDispatch ) { - special.postDispatch.call( this, event ); - } - - return event.result; - }, - - handlers: function( event, handlers ) { - var i, handleObj, sel, matchedHandlers, matchedSelectors, - handlerQueue = [], - delegateCount = handlers.delegateCount, - cur = event.target; - - // Find delegate handlers - if ( delegateCount && - - // Support: IE <=9 - // Black-hole SVG instance trees (trac-13180) - cur.nodeType && - - // Support: Firefox <=42 - // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) - // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click - // Support: IE 11 only - // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) - !( event.type === "click" && event.button >= 1 ) ) { - - for ( ; cur !== this; cur = cur.parentNode || this ) { - - // Don't check non-elements (#13208) - // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) - if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { - matchedHandlers = []; - matchedSelectors = {}; - for ( i = 0; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; - - // Don't conflict with Object.prototype properties (#13203) - sel = handleObj.selector + " "; - - if ( matchedSelectors[ sel ] === undefined ) { - matchedSelectors[ sel ] = handleObj.needsContext ? - jQuery( sel, this ).index( cur ) > -1 : - jQuery.find( sel, this, null, [ cur ] ).length; - } - if ( matchedSelectors[ sel ] ) { - matchedHandlers.push( handleObj ); - } - } - if ( matchedHandlers.length ) { - handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); - } - } - } - } - - // Add the remaining (directly-bound) handlers - cur = this; - if ( delegateCount < handlers.length ) { - handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); - } - - return handlerQueue; - }, - - addProp: function( name, hook ) { - Object.defineProperty( jQuery.Event.prototype, name, { - enumerable: true, - configurable: true, - - get: jQuery.isFunction( hook ) ? - function() { - if ( this.originalEvent ) { - return hook( this.originalEvent ); - } - } : - function() { - if ( this.originalEvent ) { - return this.originalEvent[ name ]; - } - }, - - set: function( value ) { - Object.defineProperty( this, name, { - enumerable: true, - configurable: true, - writable: true, - value: value - } ); - } - } ); - }, - - fix: function( originalEvent ) { - return originalEvent[ jQuery.expando ] ? - originalEvent : - new jQuery.Event( originalEvent ); - }, - - special: { - load: { - - // Prevent triggered image.load events from bubbling to window.load - noBubble: true - }, - focus: { - - // Fire native event if possible so blur/focus sequence is correct - trigger: function() { - if ( this !== safeActiveElement() && this.focus ) { - this.focus(); - return false; - } - }, - delegateType: "focusin" - }, - blur: { - trigger: function() { - if ( this === safeActiveElement() && this.blur ) { - this.blur(); - return false; - } - }, - delegateType: "focusout" - }, - click: { - - // For checkbox, fire native event so checked state will be right - trigger: function() { - if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { - this.click(); - return false; - } - }, - - // For cross-browser consistency, don't fire native .click() on links - _default: function( event ) { - return jQuery.nodeName( event.target, "a" ); - } - }, - - beforeunload: { - postDispatch: function( event ) { - - // Support: Firefox 20+ - // Firefox doesn't alert if the returnValue field is not set. - if ( event.result !== undefined && event.originalEvent ) { - event.originalEvent.returnValue = event.result; - } - } - } - } -}; - -jQuery.removeEvent = function( elem, type, handle ) { - - // This "if" is needed for plain objects - if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle ); - } -}; - -jQuery.Event = function( src, props ) { - - // Allow instantiation without the 'new' keyword - if ( !( this instanceof jQuery.Event ) ) { - return new jQuery.Event( src, props ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = src.defaultPrevented || - src.defaultPrevented === undefined && - - // Support: Android <=2.3 only - src.returnValue === false ? - returnTrue : - returnFalse; - - // Create target properties - // Support: Safari <=6 - 7 only - // Target should not be a text node (#504, #13143) - this.target = ( src.target && src.target.nodeType === 3 ) ? - src.target.parentNode : - src.target; - - this.currentTarget = src.currentTarget; - this.relatedTarget = src.relatedTarget; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if ( props ) { - jQuery.extend( this, props ); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || jQuery.now(); - - // Mark it as fixed - this[ jQuery.expando ] = true; -}; - -// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html -jQuery.Event.prototype = { - constructor: jQuery.Event, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse, - isSimulated: false, - - preventDefault: function() { - var e = this.originalEvent; - - this.isDefaultPrevented = returnTrue; - - if ( e && !this.isSimulated ) { - e.preventDefault(); - } - }, - stopPropagation: function() { - var e = this.originalEvent; - - this.isPropagationStopped = returnTrue; - - if ( e && !this.isSimulated ) { - e.stopPropagation(); - } - }, - stopImmediatePropagation: function() { - var e = this.originalEvent; - - this.isImmediatePropagationStopped = returnTrue; - - if ( e && !this.isSimulated ) { - e.stopImmediatePropagation(); - } - - this.stopPropagation(); - } -}; - -// Includes all common event props including KeyEvent and MouseEvent specific props -jQuery.each( { - altKey: true, - bubbles: true, - cancelable: true, - changedTouches: true, - ctrlKey: true, - detail: true, - eventPhase: true, - metaKey: true, - pageX: true, - pageY: true, - shiftKey: true, - view: true, - "char": true, - charCode: true, - key: true, - keyCode: true, - button: true, - buttons: true, - clientX: true, - clientY: true, - offsetX: true, - offsetY: true, - pointerId: true, - pointerType: true, - screenX: true, - screenY: true, - targetTouches: true, - toElement: true, - touches: true, - - which: function( event ) { - var button = event.button; - - // Add which for key events - if ( event.which == null && rkeyEvent.test( event.type ) ) { - return event.charCode != null ? event.charCode : event.keyCode; - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { - if ( button & 1 ) { - return 1; - } - - if ( button & 2 ) { - return 3; - } - - if ( button & 4 ) { - return 2; - } - - return 0; - } - - return event.which; - } -}, jQuery.event.addProp ); - -// Create mouseenter/leave events using mouseover/out and event-time checks -// so that event delegation works in jQuery. -// Do the same for pointerenter/pointerleave and pointerover/pointerout -// -// Support: Safari 7 only -// Safari sends mouseenter too often; see: -// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 -// for the description of the bug (it existed in older Chrome versions as well). -jQuery.each( { - mouseenter: "mouseover", - mouseleave: "mouseout", - pointerenter: "pointerover", - pointerleave: "pointerout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = { - delegateType: fix, - bindType: fix, - - handle: function( event ) { - var ret, - target = this, - related = event.relatedTarget, - handleObj = event.handleObj; - - // For mouseenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { - event.type = handleObj.origType; - ret = handleObj.handler.apply( this, arguments ); - event.type = fix; - } - return ret; - } - }; -} ); - -jQuery.fn.extend( { - - on: function( types, selector, data, fn ) { - return on( this, types, selector, data, fn ); - }, - one: function( types, selector, data, fn ) { - return on( this, types, selector, data, fn, 1 ); - }, - off: function( types, selector, fn ) { - var handleObj, type; - if ( types && types.preventDefault && types.handleObj ) { - - // ( event ) dispatched jQuery.Event - handleObj = types.handleObj; - jQuery( types.delegateTarget ).off( - handleObj.namespace ? - handleObj.origType + "." + handleObj.namespace : - handleObj.origType, - handleObj.selector, - handleObj.handler - ); - return this; - } - if ( typeof types === "object" ) { - - // ( types-object [, selector] ) - for ( type in types ) { - this.off( type, selector, types[ type ] ); - } - return this; - } - if ( selector === false || typeof selector === "function" ) { - - // ( types [, fn] ) - fn = selector; - selector = undefined; - } - if ( fn === false ) { - fn = returnFalse; - } - return this.each( function() { - jQuery.event.remove( this, types, fn, selector ); - } ); - } -} ); - - -var - - /* eslint-disable max-len */ - - // See https://github.com/eslint/eslint/issues/3229 - rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, - - /* eslint-enable */ - - // Support: IE <=10 - 11, Edge 12 - 13 - // In IE/Edge using regex groups here causes severe slowdowns. - // See https://connect.microsoft.com/IE/feedback/details/1736512/ - rnoInnerhtml = /\s*$/g; - -function manipulationTarget( elem, content ) { - if ( jQuery.nodeName( elem, "table" ) && - jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { - - return elem.getElementsByTagName( "tbody" )[ 0 ] || elem; - } - - return elem; -} - -// Replace/restore the type attribute of script elements for safe DOM manipulation -function disableScript( elem ) { - elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; - return elem; -} -function restoreScript( elem ) { - var match = rscriptTypeMasked.exec( elem.type ); - - if ( match ) { - elem.type = match[ 1 ]; - } else { - elem.removeAttribute( "type" ); - } - - return elem; -} - -function cloneCopyEvent( src, dest ) { - var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; - - if ( dest.nodeType !== 1 ) { - return; - } - - // 1. Copy private data: events, handlers, etc. - if ( dataPriv.hasData( src ) ) { - pdataOld = dataPriv.access( src ); - pdataCur = dataPriv.set( dest, pdataOld ); - events = pdataOld.events; - - if ( events ) { - delete pdataCur.handle; - pdataCur.events = {}; - - for ( type in events ) { - for ( i = 0, l = events[ type ].length; i < l; i++ ) { - jQuery.event.add( dest, type, events[ type ][ i ] ); - } - } - } - } - - // 2. Copy user data - if ( dataUser.hasData( src ) ) { - udataOld = dataUser.access( src ); - udataCur = jQuery.extend( {}, udataOld ); - - dataUser.set( dest, udataCur ); - } -} - -// Fix IE bugs, see support tests -function fixInput( src, dest ) { - var nodeName = dest.nodeName.toLowerCase(); - - // Fails to persist the checked state of a cloned checkbox or radio button. - if ( nodeName === "input" && rcheckableType.test( src.type ) ) { - dest.checked = src.checked; - - // Fails to return the selected option to the default selected state when cloning options - } else if ( nodeName === "input" || nodeName === "textarea" ) { - dest.defaultValue = src.defaultValue; - } -} - -function domManip( collection, args, callback, ignored ) { - - // Flatten any nested arrays - args = concat.apply( [], args ); - - var fragment, first, scripts, hasScripts, node, doc, - i = 0, - l = collection.length, - iNoClone = l - 1, - value = args[ 0 ], - isFunction = jQuery.isFunction( value ); - - // We can't cloneNode fragments that contain checked, in WebKit - if ( isFunction || - ( l > 1 && typeof value === "string" && - !support.checkClone && rchecked.test( value ) ) ) { - return collection.each( function( index ) { - var self = collection.eq( index ); - if ( isFunction ) { - args[ 0 ] = value.call( this, index, self.html() ); - } - domManip( self, args, callback, ignored ); - } ); - } - - if ( l ) { - fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); - first = fragment.firstChild; - - if ( fragment.childNodes.length === 1 ) { - fragment = first; - } - - // Require either new content or an interest in ignored elements to invoke the callback - if ( first || ignored ) { - scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); - hasScripts = scripts.length; - - // Use the original fragment for the last item - // instead of the first because it can end up - // being emptied incorrectly in certain situations (#8070). - for ( ; i < l; i++ ) { - node = fragment; - - if ( i !== iNoClone ) { - node = jQuery.clone( node, true, true ); - - // Keep references to cloned scripts for later restoration - if ( hasScripts ) { - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( scripts, getAll( node, "script" ) ); - } - } - - callback.call( collection[ i ], node, i ); - } - - if ( hasScripts ) { - doc = scripts[ scripts.length - 1 ].ownerDocument; - - // Reenable scripts - jQuery.map( scripts, restoreScript ); - - // Evaluate executable scripts on first document insertion - for ( i = 0; i < hasScripts; i++ ) { - node = scripts[ i ]; - if ( rscriptType.test( node.type || "" ) && - !dataPriv.access( node, "globalEval" ) && - jQuery.contains( doc, node ) ) { - - if ( node.src ) { - - // Optional AJAX dependency, but won't run scripts if not present - if ( jQuery._evalUrl ) { - jQuery._evalUrl( node.src ); - } - } else { - DOMEval( node.textContent.replace( rcleanScript, "" ), doc ); - } - } - } - } - } - } - - return collection; -} - -function remove( elem, selector, keepData ) { - var node, - nodes = selector ? jQuery.filter( selector, elem ) : elem, - i = 0; - - for ( ; ( node = nodes[ i ] ) != null; i++ ) { - if ( !keepData && node.nodeType === 1 ) { - jQuery.cleanData( getAll( node ) ); - } - - if ( node.parentNode ) { - if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { - setGlobalEval( getAll( node, "script" ) ); - } - node.parentNode.removeChild( node ); - } - } - - return elem; -} - -jQuery.extend( { - htmlPrefilter: function( html ) { - return html.replace( rxhtmlTag, "<$1>" ); - }, - - clone: function( elem, dataAndEvents, deepDataAndEvents ) { - var i, l, srcElements, destElements, - clone = elem.cloneNode( true ), - inPage = jQuery.contains( elem.ownerDocument, elem ); - - // Fix IE cloning issues - if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && - !jQuery.isXMLDoc( elem ) ) { - - // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 - destElements = getAll( clone ); - srcElements = getAll( elem ); - - for ( i = 0, l = srcElements.length; i < l; i++ ) { - fixInput( srcElements[ i ], destElements[ i ] ); - } - } - - // Copy the events from the original to the clone - if ( dataAndEvents ) { - if ( deepDataAndEvents ) { - srcElements = srcElements || getAll( elem ); - destElements = destElements || getAll( clone ); - - for ( i = 0, l = srcElements.length; i < l; i++ ) { - cloneCopyEvent( srcElements[ i ], destElements[ i ] ); - } - } else { - cloneCopyEvent( elem, clone ); - } - } - - // Preserve script evaluation history - destElements = getAll( clone, "script" ); - if ( destElements.length > 0 ) { - setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); - } - - // Return the cloned set - return clone; - }, - - cleanData: function( elems ) { - var data, elem, type, - special = jQuery.event.special, - i = 0; - - for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { - if ( acceptData( elem ) ) { - if ( ( data = elem[ dataPriv.expando ] ) ) { - if ( data.events ) { - for ( type in data.events ) { - if ( special[ type ] ) { - jQuery.event.remove( elem, type ); - - // This is a shortcut to avoid jQuery.event.remove's overhead - } else { - jQuery.removeEvent( elem, type, data.handle ); - } - } - } - - // Support: Chrome <=35 - 45+ - // Assign undefined instead of using delete, see Data#remove - elem[ dataPriv.expando ] = undefined; - } - if ( elem[ dataUser.expando ] ) { - - // Support: Chrome <=35 - 45+ - // Assign undefined instead of using delete, see Data#remove - elem[ dataUser.expando ] = undefined; - } - } - } - } -} ); - -jQuery.fn.extend( { - detach: function( selector ) { - return remove( this, selector, true ); - }, - - remove: function( selector ) { - return remove( this, selector ); - }, - - text: function( value ) { - return access( this, function( value ) { - return value === undefined ? - jQuery.text( this ) : - this.empty().each( function() { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - this.textContent = value; - } - } ); - }, null, value, arguments.length ); - }, - - append: function() { - return domManip( this, arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.appendChild( elem ); - } - } ); - }, - - prepend: function() { - return domManip( this, arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.insertBefore( elem, target.firstChild ); - } - } ); - }, - - before: function() { - return domManip( this, arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this ); - } - } ); - }, - - after: function() { - return domManip( this, arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this.nextSibling ); - } - } ); - }, - - empty: function() { - var elem, - i = 0; - - for ( ; ( elem = this[ i ] ) != null; i++ ) { - if ( elem.nodeType === 1 ) { - - // Prevent memory leaks - jQuery.cleanData( getAll( elem, false ) ); - - // Remove any remaining nodes - elem.textContent = ""; - } - } - - return this; - }, - - clone: function( dataAndEvents, deepDataAndEvents ) { - dataAndEvents = dataAndEvents == null ? false : dataAndEvents; - deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; - - return this.map( function() { - return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); - } ); - }, - - html: function( value ) { - return access( this, function( value ) { - var elem = this[ 0 ] || {}, - i = 0, - l = this.length; - - if ( value === undefined && elem.nodeType === 1 ) { - return elem.innerHTML; - } - - // See if we can take a shortcut and just use innerHTML - if ( typeof value === "string" && !rnoInnerhtml.test( value ) && - !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { - - value = jQuery.htmlPrefilter( value ); - - try { - for ( ; i < l; i++ ) { - elem = this[ i ] || {}; - - // Remove element nodes and prevent memory leaks - if ( elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem, false ) ); - elem.innerHTML = value; - } - } - - elem = 0; - - // If using innerHTML throws an exception, use the fallback method - } catch ( e ) {} - } - - if ( elem ) { - this.empty().append( value ); - } - }, null, value, arguments.length ); - }, - - replaceWith: function() { - var ignored = []; - - // Make the changes, replacing each non-ignored context element with the new content - return domManip( this, arguments, function( elem ) { - var parent = this.parentNode; - - if ( jQuery.inArray( this, ignored ) < 0 ) { - jQuery.cleanData( getAll( this ) ); - if ( parent ) { - parent.replaceChild( elem, this ); - } - } - - // Force callback invocation - }, ignored ); - } -} ); - -jQuery.each( { - appendTo: "append", - prependTo: "prepend", - insertBefore: "before", - insertAfter: "after", - replaceAll: "replaceWith" -}, function( name, original ) { - jQuery.fn[ name ] = function( selector ) { - var elems, - ret = [], - insert = jQuery( selector ), - last = insert.length - 1, - i = 0; - - for ( ; i <= last; i++ ) { - elems = i === last ? this : this.clone( true ); - jQuery( insert[ i ] )[ original ]( elems ); - - // Support: Android <=4.0 only, PhantomJS 1 only - // .get() because push.apply(_, arraylike) throws on ancient WebKit - push.apply( ret, elems.get() ); - } - - return this.pushStack( ret ); - }; -} ); -var rmargin = ( /^margin/ ); - -var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); - -var getStyles = function( elem ) { - - // Support: IE <=11 only, Firefox <=30 (#15098, #14150) - // IE throws on elements created in popups - // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" - var view = elem.ownerDocument.defaultView; - - if ( !view || !view.opener ) { - view = window; - } - - return view.getComputedStyle( elem ); - }; - - - -( function() { - - // Executing both pixelPosition & boxSizingReliable tests require only one layout - // so they're executed at the same time to save the second computation. - function computeStyleTests() { - - // This is a singleton, we need to execute it only once - if ( !div ) { - return; - } - - div.style.cssText = - "box-sizing:border-box;" + - "position:relative;display:block;" + - "margin:auto;border:1px;padding:1px;" + - "top:1%;width:50%"; - div.innerHTML = ""; - documentElement.appendChild( container ); - - var divStyle = window.getComputedStyle( div ); - pixelPositionVal = divStyle.top !== "1%"; - - // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 - reliableMarginLeftVal = divStyle.marginLeft === "2px"; - boxSizingReliableVal = divStyle.width === "4px"; - - // Support: Android 4.0 - 4.3 only - // Some styles come back with percentage values, even though they shouldn't - div.style.marginRight = "50%"; - pixelMarginRightVal = divStyle.marginRight === "4px"; - - documentElement.removeChild( container ); - - // Nullify the div so it wouldn't be stored in the memory and - // it will also be a sign that checks already performed - div = null; - } - - var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal, - container = document.createElement( "div" ), - div = document.createElement( "div" ); - - // Finish early in limited (non-browser) environments - if ( !div.style ) { - return; - } - - // Support: IE <=9 - 11 only - // Style of cloned element affects source element cloned (#8908) - div.style.backgroundClip = "content-box"; - div.cloneNode( true ).style.backgroundClip = ""; - support.clearCloneStyle = div.style.backgroundClip === "content-box"; - - container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" + - "padding:0;margin-top:1px;position:absolute"; - container.appendChild( div ); - - jQuery.extend( support, { - pixelPosition: function() { - computeStyleTests(); - return pixelPositionVal; - }, - boxSizingReliable: function() { - computeStyleTests(); - return boxSizingReliableVal; - }, - pixelMarginRight: function() { - computeStyleTests(); - return pixelMarginRightVal; - }, - reliableMarginLeft: function() { - computeStyleTests(); - return reliableMarginLeftVal; - } - } ); -} )(); - - -function curCSS( elem, name, computed ) { - var width, minWidth, maxWidth, ret, - style = elem.style; - - computed = computed || getStyles( elem ); - - // Support: IE <=9 only - // getPropertyValue is only needed for .css('filter') (#12537) - if ( computed ) { - ret = computed.getPropertyValue( name ) || computed[ name ]; - - if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { - ret = jQuery.style( elem, name ); - } - - // A tribute to the "awesome hack by Dean Edwards" - // Android Browser returns percentage for some values, - // but width seems to be reliably pixels. - // This is against the CSSOM draft spec: - // https://drafts.csswg.org/cssom/#resolved-values - if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) { - - // Remember the original values - width = style.width; - minWidth = style.minWidth; - maxWidth = style.maxWidth; - - // Put in the new values to get a computed value out - style.minWidth = style.maxWidth = style.width = ret; - ret = computed.width; - - // Revert the changed values - style.width = width; - style.minWidth = minWidth; - style.maxWidth = maxWidth; - } - } - - return ret !== undefined ? - - // Support: IE <=9 - 11 only - // IE returns zIndex value as an integer. - ret + "" : - ret; -} - - -function addGetHookIf( conditionFn, hookFn ) { - - // Define the hook, we'll check on the first run if it's really needed. - return { - get: function() { - if ( conditionFn() ) { - - // Hook not needed (or it's not possible to use it due - // to missing dependency), remove it. - delete this.get; - return; - } - - // Hook needed; redefine it so that the support test is not executed again. - return ( this.get = hookFn ).apply( this, arguments ); - } - }; -} - - -var - - // Swappable if display is none or starts with table - // except "table", "table-cell", or "table-caption" - // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display - rdisplayswap = /^(none|table(?!-c[ea]).+)/, - cssShow = { position: "absolute", visibility: "hidden", display: "block" }, - cssNormalTransform = { - letterSpacing: "0", - fontWeight: "400" - }, - - cssPrefixes = [ "Webkit", "Moz", "ms" ], - emptyStyle = document.createElement( "div" ).style; - -// Return a css property mapped to a potentially vendor prefixed property -function vendorPropName( name ) { - - // Shortcut for names that are not vendor prefixed - if ( name in emptyStyle ) { - return name; - } - - // Check for vendor prefixed names - var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), - i = cssPrefixes.length; - - while ( i-- ) { - name = cssPrefixes[ i ] + capName; - if ( name in emptyStyle ) { - return name; - } - } -} - -function setPositiveNumber( elem, value, subtract ) { - - // Any relative (+/-) values have already been - // normalized at this point - var matches = rcssNum.exec( value ); - return matches ? - - // Guard against undefined "subtract", e.g., when used as in cssHooks - Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : - value; -} - -function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { - var i, - val = 0; - - // If we already have the right measurement, avoid augmentation - if ( extra === ( isBorderBox ? "border" : "content" ) ) { - i = 4; - - // Otherwise initialize for horizontal or vertical properties - } else { - i = name === "width" ? 1 : 0; - } - - for ( ; i < 4; i += 2 ) { - - // Both box models exclude margin, so add it if we want it - if ( extra === "margin" ) { - val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); - } - - if ( isBorderBox ) { - - // border-box includes padding, so remove it if we want content - if ( extra === "content" ) { - val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); - } - - // At this point, extra isn't border nor margin, so remove border - if ( extra !== "margin" ) { - val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - } - } else { - - // At this point, extra isn't content, so add padding - val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); - - // At this point, extra isn't content nor padding, so add border - if ( extra !== "padding" ) { - val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - } - } - } - - return val; -} - -function getWidthOrHeight( elem, name, extra ) { - - // Start with offset property, which is equivalent to the border-box value - var val, - valueIsBorderBox = true, - styles = getStyles( elem ), - isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; - - // Support: IE <=11 only - // Running getBoundingClientRect on a disconnected node - // in IE throws an error. - if ( elem.getClientRects().length ) { - val = elem.getBoundingClientRect()[ name ]; - } - - // Some non-html elements return undefined for offsetWidth, so check for null/undefined - // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 - // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 - if ( val <= 0 || val == null ) { - - // Fall back to computed then uncomputed css if necessary - val = curCSS( elem, name, styles ); - if ( val < 0 || val == null ) { - val = elem.style[ name ]; - } - - // Computed unit is not pixels. Stop here and return. - if ( rnumnonpx.test( val ) ) { - return val; - } - - // Check for style in case a browser which returns unreliable values - // for getComputedStyle silently falls back to the reliable elem.style - valueIsBorderBox = isBorderBox && - ( support.boxSizingReliable() || val === elem.style[ name ] ); - - // Normalize "", auto, and prepare for extra - val = parseFloat( val ) || 0; - } - - // Use the active box-sizing model to add/subtract irrelevant styles - return ( val + - augmentWidthOrHeight( - elem, - name, - extra || ( isBorderBox ? "border" : "content" ), - valueIsBorderBox, - styles - ) - ) + "px"; -} - -jQuery.extend( { - - // Add in style property hooks for overriding the default - // behavior of getting and setting a style property - cssHooks: { - opacity: { - get: function( elem, computed ) { - if ( computed ) { - - // We should always get a number back from opacity - var ret = curCSS( elem, "opacity" ); - return ret === "" ? "1" : ret; - } - } - } - }, - - // Don't automatically add "px" to these possibly-unitless properties - cssNumber: { - "animationIterationCount": true, - "columnCount": true, - "fillOpacity": true, - "flexGrow": true, - "flexShrink": true, - "fontWeight": true, - "lineHeight": true, - "opacity": true, - "order": true, - "orphans": true, - "widows": true, - "zIndex": true, - "zoom": true - }, - - // Add in properties whose names you wish to fix before - // setting or getting the value - cssProps: { - "float": "cssFloat" - }, - - // Get and set the style property on a DOM Node - style: function( elem, name, value, extra ) { - - // Don't set styles on text and comment nodes - if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { - return; - } - - // Make sure that we're working with the right name - var ret, type, hooks, - origName = jQuery.camelCase( name ), - style = elem.style; - - name = jQuery.cssProps[ origName ] || - ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName ); - - // Gets hook for the prefixed version, then unprefixed version - hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; - - // Check if we're setting a value - if ( value !== undefined ) { - type = typeof value; - - // Convert "+=" or "-=" to relative numbers (#7345) - if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { - value = adjustCSS( elem, name, ret ); - - // Fixes bug #9237 - type = "number"; - } - - // Make sure that null and NaN values aren't set (#7116) - if ( value == null || value !== value ) { - return; - } - - // If a number was passed in, add the unit (except for certain CSS properties) - if ( type === "number" ) { - value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); - } - - // background-* props affect original clone's values - if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { - style[ name ] = "inherit"; - } - - // If a hook was provided, use that value, otherwise just set the specified value - if ( !hooks || !( "set" in hooks ) || - ( value = hooks.set( elem, value, extra ) ) !== undefined ) { - - style[ name ] = value; - } - - } else { - - // If a hook was provided get the non-computed value from there - if ( hooks && "get" in hooks && - ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { - - return ret; - } - - // Otherwise just get the value from the style object - return style[ name ]; - } - }, - - css: function( elem, name, extra, styles ) { - var val, num, hooks, - origName = jQuery.camelCase( name ); - - // Make sure that we're working with the right name - name = jQuery.cssProps[ origName ] || - ( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName ); - - // Try prefixed name followed by the unprefixed name - hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; - - // If a hook was provided get the computed value from there - if ( hooks && "get" in hooks ) { - val = hooks.get( elem, true, extra ); - } - - // Otherwise, if a way to get the computed value exists, use that - if ( val === undefined ) { - val = curCSS( elem, name, styles ); - } - - // Convert "normal" to computed value - if ( val === "normal" && name in cssNormalTransform ) { - val = cssNormalTransform[ name ]; - } - - // Make numeric if forced or a qualifier was provided and val looks numeric - if ( extra === "" || extra ) { - num = parseFloat( val ); - return extra === true || isFinite( num ) ? num || 0 : val; - } - return val; - } -} ); - -jQuery.each( [ "height", "width" ], function( i, name ) { - jQuery.cssHooks[ name ] = { - get: function( elem, computed, extra ) { - if ( computed ) { - - // Certain elements can have dimension info if we invisibly show them - // but it must have a current display style that would benefit - return rdisplayswap.test( jQuery.css( elem, "display" ) ) && - - // Support: Safari 8+ - // Table columns in Safari have non-zero offsetWidth & zero - // getBoundingClientRect().width unless display is changed. - // Support: IE <=11 only - // Running getBoundingClientRect on a disconnected node - // in IE throws an error. - ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? - swap( elem, cssShow, function() { - return getWidthOrHeight( elem, name, extra ); - } ) : - getWidthOrHeight( elem, name, extra ); - } - }, - - set: function( elem, value, extra ) { - var matches, - styles = extra && getStyles( elem ), - subtract = extra && augmentWidthOrHeight( - elem, - name, - extra, - jQuery.css( elem, "boxSizing", false, styles ) === "border-box", - styles - ); - - // Convert to pixels if value adjustment is needed - if ( subtract && ( matches = rcssNum.exec( value ) ) && - ( matches[ 3 ] || "px" ) !== "px" ) { - - elem.style[ name ] = value; - value = jQuery.css( elem, name ); - } - - return setPositiveNumber( elem, value, subtract ); - } - }; -} ); - -jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, - function( elem, computed ) { - if ( computed ) { - return ( parseFloat( curCSS( elem, "marginLeft" ) ) || - elem.getBoundingClientRect().left - - swap( elem, { marginLeft: 0 }, function() { - return elem.getBoundingClientRect().left; - } ) - ) + "px"; - } - } -); - -// These hooks are used by animate to expand properties -jQuery.each( { - margin: "", - padding: "", - border: "Width" -}, function( prefix, suffix ) { - jQuery.cssHooks[ prefix + suffix ] = { - expand: function( value ) { - var i = 0, - expanded = {}, - - // Assumes a single number if not a string - parts = typeof value === "string" ? value.split( " " ) : [ value ]; - - for ( ; i < 4; i++ ) { - expanded[ prefix + cssExpand[ i ] + suffix ] = - parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; - } - - return expanded; - } - }; - - if ( !rmargin.test( prefix ) ) { - jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; - } -} ); - -jQuery.fn.extend( { - css: function( name, value ) { - return access( this, function( elem, name, value ) { - var styles, len, - map = {}, - i = 0; - - if ( jQuery.isArray( name ) ) { - styles = getStyles( elem ); - len = name.length; - - for ( ; i < len; i++ ) { - map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); - } - - return map; - } - - return value !== undefined ? - jQuery.style( elem, name, value ) : - jQuery.css( elem, name ); - }, name, value, arguments.length > 1 ); - } -} ); - - -function Tween( elem, options, prop, end, easing ) { - return new Tween.prototype.init( elem, options, prop, end, easing ); -} -jQuery.Tween = Tween; - -Tween.prototype = { - constructor: Tween, - init: function( elem, options, prop, end, easing, unit ) { - this.elem = elem; - this.prop = prop; - this.easing = easing || jQuery.easing._default; - this.options = options; - this.start = this.now = this.cur(); - this.end = end; - this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); - }, - cur: function() { - var hooks = Tween.propHooks[ this.prop ]; - - return hooks && hooks.get ? - hooks.get( this ) : - Tween.propHooks._default.get( this ); - }, - run: function( percent ) { - var eased, - hooks = Tween.propHooks[ this.prop ]; - - if ( this.options.duration ) { - this.pos = eased = jQuery.easing[ this.easing ]( - percent, this.options.duration * percent, 0, 1, this.options.duration - ); - } else { - this.pos = eased = percent; - } - this.now = ( this.end - this.start ) * eased + this.start; - - if ( this.options.step ) { - this.options.step.call( this.elem, this.now, this ); - } - - if ( hooks && hooks.set ) { - hooks.set( this ); - } else { - Tween.propHooks._default.set( this ); - } - return this; - } -}; - -Tween.prototype.init.prototype = Tween.prototype; - -Tween.propHooks = { - _default: { - get: function( tween ) { - var result; - - // Use a property on the element directly when it is not a DOM element, - // or when there is no matching style property that exists. - if ( tween.elem.nodeType !== 1 || - tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { - return tween.elem[ tween.prop ]; - } - - // Passing an empty string as a 3rd parameter to .css will automatically - // attempt a parseFloat and fallback to a string if the parse fails. - // Simple values such as "10px" are parsed to Float; - // complex values such as "rotate(1rad)" are returned as-is. - result = jQuery.css( tween.elem, tween.prop, "" ); - - // Empty strings, null, undefined and "auto" are converted to 0. - return !result || result === "auto" ? 0 : result; - }, - set: function( tween ) { - - // Use step hook for back compat. - // Use cssHook if its there. - // Use .style if available and use plain properties where available. - if ( jQuery.fx.step[ tween.prop ] ) { - jQuery.fx.step[ tween.prop ]( tween ); - } else if ( tween.elem.nodeType === 1 && - ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || - jQuery.cssHooks[ tween.prop ] ) ) { - jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); - } else { - tween.elem[ tween.prop ] = tween.now; - } - } - } -}; - -// Support: IE <=9 only -// Panic based approach to setting things on disconnected nodes -Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { - set: function( tween ) { - if ( tween.elem.nodeType && tween.elem.parentNode ) { - tween.elem[ tween.prop ] = tween.now; - } - } -}; - -jQuery.easing = { - linear: function( p ) { - return p; - }, - swing: function( p ) { - return 0.5 - Math.cos( p * Math.PI ) / 2; - }, - _default: "swing" -}; - -jQuery.fx = Tween.prototype.init; - -// Back compat <1.8 extension point -jQuery.fx.step = {}; - - - - -var - fxNow, timerId, - rfxtypes = /^(?:toggle|show|hide)$/, - rrun = /queueHooks$/; - -function raf() { - if ( timerId ) { - window.requestAnimationFrame( raf ); - jQuery.fx.tick(); - } -} - -// Animations created synchronously will run synchronously -function createFxNow() { - window.setTimeout( function() { - fxNow = undefined; - } ); - return ( fxNow = jQuery.now() ); -} - -// Generate parameters to create a standard animation -function genFx( type, includeWidth ) { - var which, - i = 0, - attrs = { height: type }; - - // If we include width, step value is 1 to do all cssExpand values, - // otherwise step value is 2 to skip over Left and Right - includeWidth = includeWidth ? 1 : 0; - for ( ; i < 4; i += 2 - includeWidth ) { - which = cssExpand[ i ]; - attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; - } - - if ( includeWidth ) { - attrs.opacity = attrs.width = type; - } - - return attrs; -} - -function createTween( value, prop, animation ) { - var tween, - collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), - index = 0, - length = collection.length; - for ( ; index < length; index++ ) { - if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { - - // We're done with this property - return tween; - } - } -} - -function defaultPrefilter( elem, props, opts ) { - var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, - isBox = "width" in props || "height" in props, - anim = this, - orig = {}, - style = elem.style, - hidden = elem.nodeType && isHiddenWithinTree( elem ), - dataShow = dataPriv.get( elem, "fxshow" ); - - // Queue-skipping animations hijack the fx hooks - if ( !opts.queue ) { - hooks = jQuery._queueHooks( elem, "fx" ); - if ( hooks.unqueued == null ) { - hooks.unqueued = 0; - oldfire = hooks.empty.fire; - hooks.empty.fire = function() { - if ( !hooks.unqueued ) { - oldfire(); - } - }; - } - hooks.unqueued++; - - anim.always( function() { - - // Ensure the complete handler is called before this completes - anim.always( function() { - hooks.unqueued--; - if ( !jQuery.queue( elem, "fx" ).length ) { - hooks.empty.fire(); - } - } ); - } ); - } - - // Detect show/hide animations - for ( prop in props ) { - value = props[ prop ]; - if ( rfxtypes.test( value ) ) { - delete props[ prop ]; - toggle = toggle || value === "toggle"; - if ( value === ( hidden ? "hide" : "show" ) ) { - - // Pretend to be hidden if this is a "show" and - // there is still data from a stopped show/hide - if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { - hidden = true; - - // Ignore all other no-op show/hide data - } else { - continue; - } - } - orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); - } - } - - // Bail out if this is a no-op like .hide().hide() - propTween = !jQuery.isEmptyObject( props ); - if ( !propTween && jQuery.isEmptyObject( orig ) ) { - return; - } - - // Restrict "overflow" and "display" styles during box animations - if ( isBox && elem.nodeType === 1 ) { - - // Support: IE <=9 - 11, Edge 12 - 13 - // Record all 3 overflow attributes because IE does not infer the shorthand - // from identically-valued overflowX and overflowY - opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; - - // Identify a display type, preferring old show/hide data over the CSS cascade - restoreDisplay = dataShow && dataShow.display; - if ( restoreDisplay == null ) { - restoreDisplay = dataPriv.get( elem, "display" ); - } - display = jQuery.css( elem, "display" ); - if ( display === "none" ) { - if ( restoreDisplay ) { - display = restoreDisplay; - } else { - - // Get nonempty value(s) by temporarily forcing visibility - showHide( [ elem ], true ); - restoreDisplay = elem.style.display || restoreDisplay; - display = jQuery.css( elem, "display" ); - showHide( [ elem ] ); - } - } - - // Animate inline elements as inline-block - if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { - if ( jQuery.css( elem, "float" ) === "none" ) { - - // Restore the original display value at the end of pure show/hide animations - if ( !propTween ) { - anim.done( function() { - style.display = restoreDisplay; - } ); - if ( restoreDisplay == null ) { - display = style.display; - restoreDisplay = display === "none" ? "" : display; - } - } - style.display = "inline-block"; - } - } - } - - if ( opts.overflow ) { - style.overflow = "hidden"; - anim.always( function() { - style.overflow = opts.overflow[ 0 ]; - style.overflowX = opts.overflow[ 1 ]; - style.overflowY = opts.overflow[ 2 ]; - } ); - } - - // Implement show/hide animations - propTween = false; - for ( prop in orig ) { - - // General show/hide setup for this element animation - if ( !propTween ) { - if ( dataShow ) { - if ( "hidden" in dataShow ) { - hidden = dataShow.hidden; - } - } else { - dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); - } - - // Store hidden/visible for toggle so `.stop().toggle()` "reverses" - if ( toggle ) { - dataShow.hidden = !hidden; - } - - // Show elements before animating them - if ( hidden ) { - showHide( [ elem ], true ); - } - - /* eslint-disable no-loop-func */ - - anim.done( function() { - - /* eslint-enable no-loop-func */ - - // The final step of a "hide" animation is actually hiding the element - if ( !hidden ) { - showHide( [ elem ] ); - } - dataPriv.remove( elem, "fxshow" ); - for ( prop in orig ) { - jQuery.style( elem, prop, orig[ prop ] ); - } - } ); - } - - // Per-property setup - propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); - if ( !( prop in dataShow ) ) { - dataShow[ prop ] = propTween.start; - if ( hidden ) { - propTween.end = propTween.start; - propTween.start = 0; - } - } - } -} - -function propFilter( props, specialEasing ) { - var index, name, easing, value, hooks; - - // camelCase, specialEasing and expand cssHook pass - for ( index in props ) { - name = jQuery.camelCase( index ); - easing = specialEasing[ name ]; - value = props[ index ]; - if ( jQuery.isArray( value ) ) { - easing = value[ 1 ]; - value = props[ index ] = value[ 0 ]; - } - - if ( index !== name ) { - props[ name ] = value; - delete props[ index ]; - } - - hooks = jQuery.cssHooks[ name ]; - if ( hooks && "expand" in hooks ) { - value = hooks.expand( value ); - delete props[ name ]; - - // Not quite $.extend, this won't overwrite existing keys. - // Reusing 'index' because we have the correct "name" - for ( index in value ) { - if ( !( index in props ) ) { - props[ index ] = value[ index ]; - specialEasing[ index ] = easing; - } - } - } else { - specialEasing[ name ] = easing; - } - } -} - -function Animation( elem, properties, options ) { - var result, - stopped, - index = 0, - length = Animation.prefilters.length, - deferred = jQuery.Deferred().always( function() { - - // Don't match elem in the :animated selector - delete tick.elem; - } ), - tick = function() { - if ( stopped ) { - return false; - } - var currentTime = fxNow || createFxNow(), - remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), - - // Support: Android 2.3 only - // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) - temp = remaining / animation.duration || 0, - percent = 1 - temp, - index = 0, - length = animation.tweens.length; - - for ( ; index < length; index++ ) { - animation.tweens[ index ].run( percent ); - } - - deferred.notifyWith( elem, [ animation, percent, remaining ] ); - - if ( percent < 1 && length ) { - return remaining; - } else { - deferred.resolveWith( elem, [ animation ] ); - return false; - } - }, - animation = deferred.promise( { - elem: elem, - props: jQuery.extend( {}, properties ), - opts: jQuery.extend( true, { - specialEasing: {}, - easing: jQuery.easing._default - }, options ), - originalProperties: properties, - originalOptions: options, - startTime: fxNow || createFxNow(), - duration: options.duration, - tweens: [], - createTween: function( prop, end ) { - var tween = jQuery.Tween( elem, animation.opts, prop, end, - animation.opts.specialEasing[ prop ] || animation.opts.easing ); - animation.tweens.push( tween ); - return tween; - }, - stop: function( gotoEnd ) { - var index = 0, - - // If we are going to the end, we want to run all the tweens - // otherwise we skip this part - length = gotoEnd ? animation.tweens.length : 0; - if ( stopped ) { - return this; - } - stopped = true; - for ( ; index < length; index++ ) { - animation.tweens[ index ].run( 1 ); - } - - // Resolve when we played the last frame; otherwise, reject - if ( gotoEnd ) { - deferred.notifyWith( elem, [ animation, 1, 0 ] ); - deferred.resolveWith( elem, [ animation, gotoEnd ] ); - } else { - deferred.rejectWith( elem, [ animation, gotoEnd ] ); - } - return this; - } - } ), - props = animation.props; - - propFilter( props, animation.opts.specialEasing ); - - for ( ; index < length; index++ ) { - result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); - if ( result ) { - if ( jQuery.isFunction( result.stop ) ) { - jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = - jQuery.proxy( result.stop, result ); - } - return result; - } - } - - jQuery.map( props, createTween, animation ); - - if ( jQuery.isFunction( animation.opts.start ) ) { - animation.opts.start.call( elem, animation ); - } - - jQuery.fx.timer( - jQuery.extend( tick, { - elem: elem, - anim: animation, - queue: animation.opts.queue - } ) - ); - - // attach callbacks from options - return animation.progress( animation.opts.progress ) - .done( animation.opts.done, animation.opts.complete ) - .fail( animation.opts.fail ) - .always( animation.opts.always ); -} - -jQuery.Animation = jQuery.extend( Animation, { - - tweeners: { - "*": [ function( prop, value ) { - var tween = this.createTween( prop, value ); - adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); - return tween; - } ] - }, - - tweener: function( props, callback ) { - if ( jQuery.isFunction( props ) ) { - callback = props; - props = [ "*" ]; - } else { - props = props.match( rnothtmlwhite ); - } - - var prop, - index = 0, - length = props.length; - - for ( ; index < length; index++ ) { - prop = props[ index ]; - Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; - Animation.tweeners[ prop ].unshift( callback ); - } - }, - - prefilters: [ defaultPrefilter ], - - prefilter: function( callback, prepend ) { - if ( prepend ) { - Animation.prefilters.unshift( callback ); - } else { - Animation.prefilters.push( callback ); - } - } -} ); - -jQuery.speed = function( speed, easing, fn ) { - var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { - complete: fn || !fn && easing || - jQuery.isFunction( speed ) && speed, - duration: speed, - easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing - }; - - // Go to the end state if fx are off or if document is hidden - if ( jQuery.fx.off || document.hidden ) { - opt.duration = 0; - - } else { - if ( typeof opt.duration !== "number" ) { - if ( opt.duration in jQuery.fx.speeds ) { - opt.duration = jQuery.fx.speeds[ opt.duration ]; - - } else { - opt.duration = jQuery.fx.speeds._default; - } - } - } - - // Normalize opt.queue - true/undefined/null -> "fx" - if ( opt.queue == null || opt.queue === true ) { - opt.queue = "fx"; - } - - // Queueing - opt.old = opt.complete; - - opt.complete = function() { - if ( jQuery.isFunction( opt.old ) ) { - opt.old.call( this ); - } - - if ( opt.queue ) { - jQuery.dequeue( this, opt.queue ); - } - }; - - return opt; -}; - -jQuery.fn.extend( { - fadeTo: function( speed, to, easing, callback ) { - - // Show any hidden elements after setting opacity to 0 - return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() - - // Animate to the value specified - .end().animate( { opacity: to }, speed, easing, callback ); - }, - animate: function( prop, speed, easing, callback ) { - var empty = jQuery.isEmptyObject( prop ), - optall = jQuery.speed( speed, easing, callback ), - doAnimation = function() { - - // Operate on a copy of prop so per-property easing won't be lost - var anim = Animation( this, jQuery.extend( {}, prop ), optall ); - - // Empty animations, or finishing resolves immediately - if ( empty || dataPriv.get( this, "finish" ) ) { - anim.stop( true ); - } - }; - doAnimation.finish = doAnimation; - - return empty || optall.queue === false ? - this.each( doAnimation ) : - this.queue( optall.queue, doAnimation ); - }, - stop: function( type, clearQueue, gotoEnd ) { - var stopQueue = function( hooks ) { - var stop = hooks.stop; - delete hooks.stop; - stop( gotoEnd ); - }; - - if ( typeof type !== "string" ) { - gotoEnd = clearQueue; - clearQueue = type; - type = undefined; - } - if ( clearQueue && type !== false ) { - this.queue( type || "fx", [] ); - } - - return this.each( function() { - var dequeue = true, - index = type != null && type + "queueHooks", - timers = jQuery.timers, - data = dataPriv.get( this ); - - if ( index ) { - if ( data[ index ] && data[ index ].stop ) { - stopQueue( data[ index ] ); - } - } else { - for ( index in data ) { - if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { - stopQueue( data[ index ] ); - } - } - } - - for ( index = timers.length; index--; ) { - if ( timers[ index ].elem === this && - ( type == null || timers[ index ].queue === type ) ) { - - timers[ index ].anim.stop( gotoEnd ); - dequeue = false; - timers.splice( index, 1 ); - } - } - - // Start the next in the queue if the last step wasn't forced. - // Timers currently will call their complete callbacks, which - // will dequeue but only if they were gotoEnd. - if ( dequeue || !gotoEnd ) { - jQuery.dequeue( this, type ); - } - } ); - }, - finish: function( type ) { - if ( type !== false ) { - type = type || "fx"; - } - return this.each( function() { - var index, - data = dataPriv.get( this ), - queue = data[ type + "queue" ], - hooks = data[ type + "queueHooks" ], - timers = jQuery.timers, - length = queue ? queue.length : 0; - - // Enable finishing flag on private data - data.finish = true; - - // Empty the queue first - jQuery.queue( this, type, [] ); - - if ( hooks && hooks.stop ) { - hooks.stop.call( this, true ); - } - - // Look for any active animations, and finish them - for ( index = timers.length; index--; ) { - if ( timers[ index ].elem === this && timers[ index ].queue === type ) { - timers[ index ].anim.stop( true ); - timers.splice( index, 1 ); - } - } - - // Look for any animations in the old queue and finish them - for ( index = 0; index < length; index++ ) { - if ( queue[ index ] && queue[ index ].finish ) { - queue[ index ].finish.call( this ); - } - } - - // Turn off finishing flag - delete data.finish; - } ); - } -} ); - -jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) { - var cssFn = jQuery.fn[ name ]; - jQuery.fn[ name ] = function( speed, easing, callback ) { - return speed == null || typeof speed === "boolean" ? - cssFn.apply( this, arguments ) : - this.animate( genFx( name, true ), speed, easing, callback ); - }; -} ); - -// Generate shortcuts for custom animations -jQuery.each( { - slideDown: genFx( "show" ), - slideUp: genFx( "hide" ), - slideToggle: genFx( "toggle" ), - fadeIn: { opacity: "show" }, - fadeOut: { opacity: "hide" }, - fadeToggle: { opacity: "toggle" } -}, function( name, props ) { - jQuery.fn[ name ] = function( speed, easing, callback ) { - return this.animate( props, speed, easing, callback ); - }; -} ); - -jQuery.timers = []; -jQuery.fx.tick = function() { - var timer, - i = 0, - timers = jQuery.timers; - - fxNow = jQuery.now(); - - for ( ; i < timers.length; i++ ) { - timer = timers[ i ]; - - // Checks the timer has not already been removed - if ( !timer() && timers[ i ] === timer ) { - timers.splice( i--, 1 ); - } - } - - if ( !timers.length ) { - jQuery.fx.stop(); - } - fxNow = undefined; -}; - -jQuery.fx.timer = function( timer ) { - jQuery.timers.push( timer ); - if ( timer() ) { - jQuery.fx.start(); - } else { - jQuery.timers.pop(); - } -}; - -jQuery.fx.interval = 13; -jQuery.fx.start = function() { - if ( !timerId ) { - timerId = window.requestAnimationFrame ? - window.requestAnimationFrame( raf ) : - window.setInterval( jQuery.fx.tick, jQuery.fx.interval ); - } -}; - -jQuery.fx.stop = function() { - if ( window.cancelAnimationFrame ) { - window.cancelAnimationFrame( timerId ); - } else { - window.clearInterval( timerId ); - } - - timerId = null; -}; - -jQuery.fx.speeds = { - slow: 600, - fast: 200, - - // Default speed - _default: 400 -}; - - -// Based off of the plugin by Clint Helfers, with permission. -// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ -jQuery.fn.delay = function( time, type ) { - time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; - type = type || "fx"; - - return this.queue( type, function( next, hooks ) { - var timeout = window.setTimeout( next, time ); - hooks.stop = function() { - window.clearTimeout( timeout ); - }; - } ); -}; - - -( function() { - var input = document.createElement( "input" ), - select = document.createElement( "select" ), - opt = select.appendChild( document.createElement( "option" ) ); - - input.type = "checkbox"; - - // Support: Android <=4.3 only - // Default value for a checkbox should be "on" - support.checkOn = input.value !== ""; - - // Support: IE <=11 only - // Must access selectedIndex to make default options select - support.optSelected = opt.selected; - - // Support: IE <=11 only - // An input loses its value after becoming a radio - input = document.createElement( "input" ); - input.value = "t"; - input.type = "radio"; - support.radioValue = input.value === "t"; -} )(); - - -var boolHook, - attrHandle = jQuery.expr.attrHandle; - -jQuery.fn.extend( { - attr: function( name, value ) { - return access( this, jQuery.attr, name, value, arguments.length > 1 ); - }, - - removeAttr: function( name ) { - return this.each( function() { - jQuery.removeAttr( this, name ); - } ); - } -} ); - -jQuery.extend( { - attr: function( elem, name, value ) { - var ret, hooks, - nType = elem.nodeType; - - // Don't get/set attributes on text, comment and attribute nodes - if ( nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - // Fallback to prop when attributes are not supported - if ( typeof elem.getAttribute === "undefined" ) { - return jQuery.prop( elem, name, value ); - } - - // Attribute hooks are determined by the lowercase version - // Grab necessary hook if one is defined - if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { - hooks = jQuery.attrHooks[ name.toLowerCase() ] || - ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); - } - - if ( value !== undefined ) { - if ( value === null ) { - jQuery.removeAttr( elem, name ); - return; - } - - if ( hooks && "set" in hooks && - ( ret = hooks.set( elem, value, name ) ) !== undefined ) { - return ret; - } - - elem.setAttribute( name, value + "" ); - return value; - } - - if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { - return ret; - } - - ret = jQuery.find.attr( elem, name ); - - // Non-existent attributes return null, we normalize to undefined - return ret == null ? undefined : ret; - }, - - attrHooks: { - type: { - set: function( elem, value ) { - if ( !support.radioValue && value === "radio" && - jQuery.nodeName( elem, "input" ) ) { - var val = elem.value; - elem.setAttribute( "type", value ); - if ( val ) { - elem.value = val; - } - return value; - } - } - } - }, - - removeAttr: function( elem, value ) { - var name, - i = 0, - - // Attribute names can contain non-HTML whitespace characters - // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 - attrNames = value && value.match( rnothtmlwhite ); - - if ( attrNames && elem.nodeType === 1 ) { - while ( ( name = attrNames[ i++ ] ) ) { - elem.removeAttribute( name ); - } - } - } -} ); - -// Hooks for boolean attributes -boolHook = { - set: function( elem, value, name ) { - if ( value === false ) { - - // Remove boolean attributes when set to false - jQuery.removeAttr( elem, name ); - } else { - elem.setAttribute( name, name ); - } - return name; - } -}; - -jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { - var getter = attrHandle[ name ] || jQuery.find.attr; - - attrHandle[ name ] = function( elem, name, isXML ) { - var ret, handle, - lowercaseName = name.toLowerCase(); - - if ( !isXML ) { - - // Avoid an infinite loop by temporarily removing this function from the getter - handle = attrHandle[ lowercaseName ]; - attrHandle[ lowercaseName ] = ret; - ret = getter( elem, name, isXML ) != null ? - lowercaseName : - null; - attrHandle[ lowercaseName ] = handle; - } - return ret; - }; -} ); - - - - -var rfocusable = /^(?:input|select|textarea|button)$/i, - rclickable = /^(?:a|area)$/i; - -jQuery.fn.extend( { - prop: function( name, value ) { - return access( this, jQuery.prop, name, value, arguments.length > 1 ); - }, - - removeProp: function( name ) { - return this.each( function() { - delete this[ jQuery.propFix[ name ] || name ]; - } ); - } -} ); - -jQuery.extend( { - prop: function( elem, name, value ) { - var ret, hooks, - nType = elem.nodeType; - - // Don't get/set properties on text, comment and attribute nodes - if ( nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { - - // Fix name and attach hooks - name = jQuery.propFix[ name ] || name; - hooks = jQuery.propHooks[ name ]; - } - - if ( value !== undefined ) { - if ( hooks && "set" in hooks && - ( ret = hooks.set( elem, value, name ) ) !== undefined ) { - return ret; - } - - return ( elem[ name ] = value ); - } - - if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { - return ret; - } - - return elem[ name ]; - }, - - propHooks: { - tabIndex: { - get: function( elem ) { - - // Support: IE <=9 - 11 only - // elem.tabIndex doesn't always return the - // correct value when it hasn't been explicitly set - // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ - // Use proper attribute retrieval(#12072) - var tabindex = jQuery.find.attr( elem, "tabindex" ); - - if ( tabindex ) { - return parseInt( tabindex, 10 ); - } - - if ( - rfocusable.test( elem.nodeName ) || - rclickable.test( elem.nodeName ) && - elem.href - ) { - return 0; - } - - return -1; - } - } - }, - - propFix: { - "for": "htmlFor", - "class": "className" - } -} ); - -// Support: IE <=11 only -// Accessing the selectedIndex property -// forces the browser to respect setting selected -// on the option -// The getter ensures a default option is selected -// when in an optgroup -// eslint rule "no-unused-expressions" is disabled for this code -// since it considers such accessions noop -if ( !support.optSelected ) { - jQuery.propHooks.selected = { - get: function( elem ) { - - /* eslint no-unused-expressions: "off" */ - - var parent = elem.parentNode; - if ( parent && parent.parentNode ) { - parent.parentNode.selectedIndex; - } - return null; - }, - set: function( elem ) { - - /* eslint no-unused-expressions: "off" */ - - var parent = elem.parentNode; - if ( parent ) { - parent.selectedIndex; - - if ( parent.parentNode ) { - parent.parentNode.selectedIndex; - } - } - } - }; -} - -jQuery.each( [ - "tabIndex", - "readOnly", - "maxLength", - "cellSpacing", - "cellPadding", - "rowSpan", - "colSpan", - "useMap", - "frameBorder", - "contentEditable" -], function() { - jQuery.propFix[ this.toLowerCase() ] = this; -} ); - - - - - // Strip and collapse whitespace according to HTML spec - // https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace - function stripAndCollapse( value ) { - var tokens = value.match( rnothtmlwhite ) || []; - return tokens.join( " " ); - } - - -function getClass( elem ) { - return elem.getAttribute && elem.getAttribute( "class" ) || ""; -} - -jQuery.fn.extend( { - addClass: function( value ) { - var classes, elem, cur, curValue, clazz, j, finalValue, - i = 0; - - if ( jQuery.isFunction( value ) ) { - return this.each( function( j ) { - jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); - } ); - } - - if ( typeof value === "string" && value ) { - classes = value.match( rnothtmlwhite ) || []; - - while ( ( elem = this[ i++ ] ) ) { - curValue = getClass( elem ); - cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); - - if ( cur ) { - j = 0; - while ( ( clazz = classes[ j++ ] ) ) { - if ( cur.indexOf( " " + clazz + " " ) < 0 ) { - cur += clazz + " "; - } - } - - // Only assign if different to avoid unneeded rendering. - finalValue = stripAndCollapse( cur ); - if ( curValue !== finalValue ) { - elem.setAttribute( "class", finalValue ); - } - } - } - } - - return this; - }, - - removeClass: function( value ) { - var classes, elem, cur, curValue, clazz, j, finalValue, - i = 0; - - if ( jQuery.isFunction( value ) ) { - return this.each( function( j ) { - jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); - } ); - } - - if ( !arguments.length ) { - return this.attr( "class", "" ); - } - - if ( typeof value === "string" && value ) { - classes = value.match( rnothtmlwhite ) || []; - - while ( ( elem = this[ i++ ] ) ) { - curValue = getClass( elem ); - - // This expression is here for better compressibility (see addClass) - cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); - - if ( cur ) { - j = 0; - while ( ( clazz = classes[ j++ ] ) ) { - - // Remove *all* instances - while ( cur.indexOf( " " + clazz + " " ) > -1 ) { - cur = cur.replace( " " + clazz + " ", " " ); - } - } - - // Only assign if different to avoid unneeded rendering. - finalValue = stripAndCollapse( cur ); - if ( curValue !== finalValue ) { - elem.setAttribute( "class", finalValue ); - } - } - } - } - - return this; - }, - - toggleClass: function( value, stateVal ) { - var type = typeof value; - - if ( typeof stateVal === "boolean" && type === "string" ) { - return stateVal ? this.addClass( value ) : this.removeClass( value ); - } - - if ( jQuery.isFunction( value ) ) { - return this.each( function( i ) { - jQuery( this ).toggleClass( - value.call( this, i, getClass( this ), stateVal ), - stateVal - ); - } ); - } - - return this.each( function() { - var className, i, self, classNames; - - if ( type === "string" ) { - - // Toggle individual class names - i = 0; - self = jQuery( this ); - classNames = value.match( rnothtmlwhite ) || []; - - while ( ( className = classNames[ i++ ] ) ) { - - // Check each className given, space separated list - if ( self.hasClass( className ) ) { - self.removeClass( className ); - } else { - self.addClass( className ); - } - } - - // Toggle whole class name - } else if ( value === undefined || type === "boolean" ) { - className = getClass( this ); - if ( className ) { - - // Store className if set - dataPriv.set( this, "__className__", className ); - } - - // If the element has a class name or if we're passed `false`, - // then remove the whole classname (if there was one, the above saved it). - // Otherwise bring back whatever was previously saved (if anything), - // falling back to the empty string if nothing was stored. - if ( this.setAttribute ) { - this.setAttribute( "class", - className || value === false ? - "" : - dataPriv.get( this, "__className__" ) || "" - ); - } - } - } ); - }, - - hasClass: function( selector ) { - var className, elem, - i = 0; - - className = " " + selector + " "; - while ( ( elem = this[ i++ ] ) ) { - if ( elem.nodeType === 1 && - ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { - return true; - } - } - - return false; - } -} ); - - - - -var rreturn = /\r/g; - -jQuery.fn.extend( { - val: function( value ) { - var hooks, ret, isFunction, - elem = this[ 0 ]; - - if ( !arguments.length ) { - if ( elem ) { - hooks = jQuery.valHooks[ elem.type ] || - jQuery.valHooks[ elem.nodeName.toLowerCase() ]; - - if ( hooks && - "get" in hooks && - ( ret = hooks.get( elem, "value" ) ) !== undefined - ) { - return ret; - } - - ret = elem.value; - - // Handle most common string cases - if ( typeof ret === "string" ) { - return ret.replace( rreturn, "" ); - } - - // Handle cases where value is null/undef or number - return ret == null ? "" : ret; - } - - return; - } - - isFunction = jQuery.isFunction( value ); - - return this.each( function( i ) { - var val; - - if ( this.nodeType !== 1 ) { - return; - } - - if ( isFunction ) { - val = value.call( this, i, jQuery( this ).val() ); - } else { - val = value; - } - - // Treat null/undefined as ""; convert numbers to string - if ( val == null ) { - val = ""; - - } else if ( typeof val === "number" ) { - val += ""; - - } else if ( jQuery.isArray( val ) ) { - val = jQuery.map( val, function( value ) { - return value == null ? "" : value + ""; - } ); - } - - hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; - - // If set returns undefined, fall back to normal setting - if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { - this.value = val; - } - } ); - } -} ); - -jQuery.extend( { - valHooks: { - option: { - get: function( elem ) { - - var val = jQuery.find.attr( elem, "value" ); - return val != null ? - val : - - // Support: IE <=10 - 11 only - // option.text throws exceptions (#14686, #14858) - // Strip and collapse whitespace - // https://html.spec.whatwg.org/#strip-and-collapse-whitespace - stripAndCollapse( jQuery.text( elem ) ); - } - }, - select: { - get: function( elem ) { - var value, option, i, - options = elem.options, - index = elem.selectedIndex, - one = elem.type === "select-one", - values = one ? null : [], - max = one ? index + 1 : options.length; - - if ( index < 0 ) { - i = max; - - } else { - i = one ? index : 0; - } - - // Loop through all the selected options - for ( ; i < max; i++ ) { - option = options[ i ]; - - // Support: IE <=9 only - // IE8-9 doesn't update selected after form reset (#2551) - if ( ( option.selected || i === index ) && - - // Don't return options that are disabled or in a disabled optgroup - !option.disabled && - ( !option.parentNode.disabled || - !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { - - // Get the specific value for the option - value = jQuery( option ).val(); - - // We don't need an array for one selects - if ( one ) { - return value; - } - - // Multi-Selects return an array - values.push( value ); - } - } - - return values; - }, - - set: function( elem, value ) { - var optionSet, option, - options = elem.options, - values = jQuery.makeArray( value ), - i = options.length; - - while ( i-- ) { - option = options[ i ]; - - /* eslint-disable no-cond-assign */ - - if ( option.selected = - jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 - ) { - optionSet = true; - } - - /* eslint-enable no-cond-assign */ - } - - // Force browsers to behave consistently when non-matching value is set - if ( !optionSet ) { - elem.selectedIndex = -1; - } - return values; - } - } - } -} ); - -// Radios and checkboxes getter/setter -jQuery.each( [ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = { - set: function( elem, value ) { - if ( jQuery.isArray( value ) ) { - return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); - } - } - }; - if ( !support.checkOn ) { - jQuery.valHooks[ this ].get = function( elem ) { - return elem.getAttribute( "value" ) === null ? "on" : elem.value; - }; - } -} ); - - - - -// Return jQuery for attributes-only inclusion - - -var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/; - -jQuery.extend( jQuery.event, { - - trigger: function( event, data, elem, onlyHandlers ) { - - var i, cur, tmp, bubbleType, ontype, handle, special, - eventPath = [ elem || document ], - type = hasOwn.call( event, "type" ) ? event.type : event, - namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; - - cur = tmp = elem = elem || document; - - // Don't do events on text and comment nodes - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - // focus/blur morphs to focusin/out; ensure we're not firing them right now - if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { - return; - } - - if ( type.indexOf( "." ) > -1 ) { - - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split( "." ); - type = namespaces.shift(); - namespaces.sort(); - } - ontype = type.indexOf( ":" ) < 0 && "on" + type; - - // Caller can pass in a jQuery.Event object, Object, or just an event type string - event = event[ jQuery.expando ] ? - event : - new jQuery.Event( type, typeof event === "object" && event ); - - // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) - event.isTrigger = onlyHandlers ? 2 : 3; - event.namespace = namespaces.join( "." ); - event.rnamespace = event.namespace ? - new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : - null; - - // Clean up the event in case it is being reused - event.result = undefined; - if ( !event.target ) { - event.target = elem; - } - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data == null ? - [ event ] : - jQuery.makeArray( data, [ event ] ); - - // Allow special events to draw outside the lines - special = jQuery.event.special[ type ] || {}; - if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { - return; - } - - // Determine event propagation path in advance, per W3C events spec (#9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { - - bubbleType = special.delegateType || type; - if ( !rfocusMorph.test( bubbleType + type ) ) { - cur = cur.parentNode; - } - for ( ; cur; cur = cur.parentNode ) { - eventPath.push( cur ); - tmp = cur; - } - - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( tmp === ( elem.ownerDocument || document ) ) { - eventPath.push( tmp.defaultView || tmp.parentWindow || window ); - } - } - - // Fire handlers on the event path - i = 0; - while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { - - event.type = i > 1 ? - bubbleType : - special.bindType || type; - - // jQuery handler - handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] && - dataPriv.get( cur, "handle" ); - if ( handle ) { - handle.apply( cur, data ); - } - - // Native handler - handle = ontype && cur[ ontype ]; - if ( handle && handle.apply && acceptData( cur ) ) { - event.result = handle.apply( cur, data ); - if ( event.result === false ) { - event.preventDefault(); - } - } - } - event.type = type; - - // If nobody prevented the default action, do it now - if ( !onlyHandlers && !event.isDefaultPrevented() ) { - - if ( ( !special._default || - special._default.apply( eventPath.pop(), data ) === false ) && - acceptData( elem ) ) { - - // Call a native DOM method on the target with the same name as the event. - // Don't do default actions on window, that's where global variables be (#6170) - if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { - - // Don't re-trigger an onFOO event when we call its FOO() method - tmp = elem[ ontype ]; - - if ( tmp ) { - elem[ ontype ] = null; - } - - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; - elem[ type ](); - jQuery.event.triggered = undefined; - - if ( tmp ) { - elem[ ontype ] = tmp; - } - } - } - } - - return event.result; - }, - - // Piggyback on a donor event to simulate a different one - // Used only for `focus(in | out)` events - simulate: function( type, elem, event ) { - var e = jQuery.extend( - new jQuery.Event(), - event, - { - type: type, - isSimulated: true - } - ); - - jQuery.event.trigger( e, null, elem ); - } - -} ); - -jQuery.fn.extend( { - - trigger: function( type, data ) { - return this.each( function() { - jQuery.event.trigger( type, data, this ); - } ); - }, - triggerHandler: function( type, data ) { - var elem = this[ 0 ]; - if ( elem ) { - return jQuery.event.trigger( type, data, elem, true ); - } - } -} ); - - -jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " + - "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + - "change select submit keydown keypress keyup contextmenu" ).split( " " ), - function( i, name ) { - - // Handle event binding - jQuery.fn[ name ] = function( data, fn ) { - return arguments.length > 0 ? - this.on( name, null, data, fn ) : - this.trigger( name ); - }; -} ); - -jQuery.fn.extend( { - hover: function( fnOver, fnOut ) { - return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); - } -} ); - - - - -support.focusin = "onfocusin" in window; - - -// Support: Firefox <=44 -// Firefox doesn't have focus(in | out) events -// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 -// -// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 -// focus(in | out) events fire after focus & blur events, -// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order -// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 -if ( !support.focusin ) { - jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { - - // Attach a single capturing handler on the document while someone wants focusin/focusout - var handler = function( event ) { - jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); - }; - - jQuery.event.special[ fix ] = { - setup: function() { - var doc = this.ownerDocument || this, - attaches = dataPriv.access( doc, fix ); - - if ( !attaches ) { - doc.addEventListener( orig, handler, true ); - } - dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); - }, - teardown: function() { - var doc = this.ownerDocument || this, - attaches = dataPriv.access( doc, fix ) - 1; - - if ( !attaches ) { - doc.removeEventListener( orig, handler, true ); - dataPriv.remove( doc, fix ); - - } else { - dataPriv.access( doc, fix, attaches ); - } - } - }; - } ); -} -var location = window.location; - -var nonce = jQuery.now(); - -var rquery = ( /\?/ ); - - - -// Cross-browser xml parsing -jQuery.parseXML = function( data ) { - var xml; - if ( !data || typeof data !== "string" ) { - return null; - } - - // Support: IE 9 - 11 only - // IE throws on parseFromString with invalid input. - try { - xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); - } catch ( e ) { - xml = undefined; - } - - if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { - jQuery.error( "Invalid XML: " + data ); - } - return xml; -}; - - -var - rbracket = /\[\]$/, - rCRLF = /\r?\n/g, - rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, - rsubmittable = /^(?:input|select|textarea|keygen)/i; - -function buildParams( prefix, obj, traditional, add ) { - var name; - - if ( jQuery.isArray( obj ) ) { - - // Serialize array item. - jQuery.each( obj, function( i, v ) { - if ( traditional || rbracket.test( prefix ) ) { - - // Treat each array item as a scalar. - add( prefix, v ); - - } else { - - // Item is non-scalar (array or object), encode its numeric index. - buildParams( - prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", - v, - traditional, - add - ); - } - } ); - - } else if ( !traditional && jQuery.type( obj ) === "object" ) { - - // Serialize object item. - for ( name in obj ) { - buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); - } - - } else { - - // Serialize scalar item. - add( prefix, obj ); - } -} - -// Serialize an array of form elements or a set of -// key/values into a query string -jQuery.param = function( a, traditional ) { - var prefix, - s = [], - add = function( key, valueOrFunction ) { - - // If value is a function, invoke it and use its return value - var value = jQuery.isFunction( valueOrFunction ) ? - valueOrFunction() : - valueOrFunction; - - s[ s.length ] = encodeURIComponent( key ) + "=" + - encodeURIComponent( value == null ? "" : value ); - }; - - // If an array was passed in, assume that it is an array of form elements. - if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { - - // Serialize the form elements - jQuery.each( a, function() { - add( this.name, this.value ); - } ); - - } else { - - // If traditional, encode the "old" way (the way 1.3.2 or older - // did it), otherwise encode params recursively. - for ( prefix in a ) { - buildParams( prefix, a[ prefix ], traditional, add ); - } - } - - // Return the resulting serialization - return s.join( "&" ); -}; - -jQuery.fn.extend( { - serialize: function() { - return jQuery.param( this.serializeArray() ); - }, - serializeArray: function() { - return this.map( function() { - - // Can add propHook for "elements" to filter or add form elements - var elements = jQuery.prop( this, "elements" ); - return elements ? jQuery.makeArray( elements ) : this; - } ) - .filter( function() { - var type = this.type; - - // Use .is( ":disabled" ) so that fieldset[disabled] works - return this.name && !jQuery( this ).is( ":disabled" ) && - rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && - ( this.checked || !rcheckableType.test( type ) ); - } ) - .map( function( i, elem ) { - var val = jQuery( this ).val(); - - if ( val == null ) { - return null; - } - - if ( jQuery.isArray( val ) ) { - return jQuery.map( val, function( val ) { - return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - } ); - } - - return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - } ).get(); - } -} ); - - -var - r20 = /%20/g, - rhash = /#.*$/, - rantiCache = /([?&])_=[^&]*/, - rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, - - // #7653, #8125, #8152: local protocol detection - rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, - rnoContent = /^(?:GET|HEAD)$/, - rprotocol = /^\/\//, - - /* Prefilters - * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) - * 2) These are called: - * - BEFORE asking for a transport - * - AFTER param serialization (s.data is a string if s.processData is true) - * 3) key is the dataType - * 4) the catchall symbol "*" can be used - * 5) execution will start with transport dataType and THEN continue down to "*" if needed - */ - prefilters = {}, - - /* Transports bindings - * 1) key is the dataType - * 2) the catchall symbol "*" can be used - * 3) selection will start with transport dataType and THEN go to "*" if needed - */ - transports = {}, - - // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression - allTypes = "*/".concat( "*" ), - - // Anchor tag for parsing the document origin - originAnchor = document.createElement( "a" ); - originAnchor.href = location.href; - -// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport -function addToPrefiltersOrTransports( structure ) { - - // dataTypeExpression is optional and defaults to "*" - return function( dataTypeExpression, func ) { - - if ( typeof dataTypeExpression !== "string" ) { - func = dataTypeExpression; - dataTypeExpression = "*"; - } - - var dataType, - i = 0, - dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; - - if ( jQuery.isFunction( func ) ) { - - // For each dataType in the dataTypeExpression - while ( ( dataType = dataTypes[ i++ ] ) ) { - - // Prepend if requested - if ( dataType[ 0 ] === "+" ) { - dataType = dataType.slice( 1 ) || "*"; - ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); - - // Otherwise append - } else { - ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); - } - } - } - }; -} - -// Base inspection function for prefilters and transports -function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { - - var inspected = {}, - seekingTransport = ( structure === transports ); - - function inspect( dataType ) { - var selected; - inspected[ dataType ] = true; - jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { - var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); - if ( typeof dataTypeOrTransport === "string" && - !seekingTransport && !inspected[ dataTypeOrTransport ] ) { - - options.dataTypes.unshift( dataTypeOrTransport ); - inspect( dataTypeOrTransport ); - return false; - } else if ( seekingTransport ) { - return !( selected = dataTypeOrTransport ); - } - } ); - return selected; - } - - return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); -} - -// A special extend for ajax options -// that takes "flat" options (not to be deep extended) -// Fixes #9887 -function ajaxExtend( target, src ) { - var key, deep, - flatOptions = jQuery.ajaxSettings.flatOptions || {}; - - for ( key in src ) { - if ( src[ key ] !== undefined ) { - ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; - } - } - if ( deep ) { - jQuery.extend( true, target, deep ); - } - - return target; -} - -/* Handles responses to an ajax request: - * - finds the right dataType (mediates between content-type and expected dataType) - * - returns the corresponding response - */ -function ajaxHandleResponses( s, jqXHR, responses ) { - - var ct, type, finalDataType, firstDataType, - contents = s.contents, - dataTypes = s.dataTypes; - - // Remove auto dataType and get content-type in the process - while ( dataTypes[ 0 ] === "*" ) { - dataTypes.shift(); - if ( ct === undefined ) { - ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); - } - } - - // Check if we're dealing with a known content-type - if ( ct ) { - for ( type in contents ) { - if ( contents[ type ] && contents[ type ].test( ct ) ) { - dataTypes.unshift( type ); - break; - } - } - } - - // Check to see if we have a response for the expected dataType - if ( dataTypes[ 0 ] in responses ) { - finalDataType = dataTypes[ 0 ]; - } else { - - // Try convertible dataTypes - for ( type in responses ) { - if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { - finalDataType = type; - break; - } - if ( !firstDataType ) { - firstDataType = type; - } - } - - // Or just use first one - finalDataType = finalDataType || firstDataType; - } - - // If we found a dataType - // We add the dataType to the list if needed - // and return the corresponding response - if ( finalDataType ) { - if ( finalDataType !== dataTypes[ 0 ] ) { - dataTypes.unshift( finalDataType ); - } - return responses[ finalDataType ]; - } -} - -/* Chain conversions given the request and the original response - * Also sets the responseXXX fields on the jqXHR instance - */ -function ajaxConvert( s, response, jqXHR, isSuccess ) { - var conv2, current, conv, tmp, prev, - converters = {}, - - // Work with a copy of dataTypes in case we need to modify it for conversion - dataTypes = s.dataTypes.slice(); - - // Create converters map with lowercased keys - if ( dataTypes[ 1 ] ) { - for ( conv in s.converters ) { - converters[ conv.toLowerCase() ] = s.converters[ conv ]; - } - } - - current = dataTypes.shift(); - - // Convert to each sequential dataType - while ( current ) { - - if ( s.responseFields[ current ] ) { - jqXHR[ s.responseFields[ current ] ] = response; - } - - // Apply the dataFilter if provided - if ( !prev && isSuccess && s.dataFilter ) { - response = s.dataFilter( response, s.dataType ); - } - - prev = current; - current = dataTypes.shift(); - - if ( current ) { - - // There's only work to do if current dataType is non-auto - if ( current === "*" ) { - - current = prev; - - // Convert response if prev dataType is non-auto and differs from current - } else if ( prev !== "*" && prev !== current ) { - - // Seek a direct converter - conv = converters[ prev + " " + current ] || converters[ "* " + current ]; - - // If none found, seek a pair - if ( !conv ) { - for ( conv2 in converters ) { - - // If conv2 outputs current - tmp = conv2.split( " " ); - if ( tmp[ 1 ] === current ) { - - // If prev can be converted to accepted input - conv = converters[ prev + " " + tmp[ 0 ] ] || - converters[ "* " + tmp[ 0 ] ]; - if ( conv ) { - - // Condense equivalence converters - if ( conv === true ) { - conv = converters[ conv2 ]; - - // Otherwise, insert the intermediate dataType - } else if ( converters[ conv2 ] !== true ) { - current = tmp[ 0 ]; - dataTypes.unshift( tmp[ 1 ] ); - } - break; - } - } - } - } - - // Apply converter (if not an equivalence) - if ( conv !== true ) { - - // Unless errors are allowed to bubble, catch and return them - if ( conv && s.throws ) { - response = conv( response ); - } else { - try { - response = conv( response ); - } catch ( e ) { - return { - state: "parsererror", - error: conv ? e : "No conversion from " + prev + " to " + current - }; - } - } - } - } - } - } - - return { state: "success", data: response }; -} - -jQuery.extend( { - - // Counter for holding the number of active queries - active: 0, - - // Last-Modified header cache for next request - lastModified: {}, - etag: {}, - - ajaxSettings: { - url: location.href, - type: "GET", - isLocal: rlocalProtocol.test( location.protocol ), - global: true, - processData: true, - async: true, - contentType: "application/x-www-form-urlencoded; charset=UTF-8", - - /* - timeout: 0, - data: null, - dataType: null, - username: null, - password: null, - cache: null, - throws: false, - traditional: false, - headers: {}, - */ - - accepts: { - "*": allTypes, - text: "text/plain", - html: "text/html", - xml: "application/xml, text/xml", - json: "application/json, text/javascript" - }, - - contents: { - xml: /\bxml\b/, - html: /\bhtml/, - json: /\bjson\b/ - }, - - responseFields: { - xml: "responseXML", - text: "responseText", - json: "responseJSON" - }, - - // Data converters - // Keys separate source (or catchall "*") and destination types with a single space - converters: { - - // Convert anything to text - "* text": String, - - // Text to html (true = no transformation) - "text html": true, - - // Evaluate text as a json expression - "text json": JSON.parse, - - // Parse text as xml - "text xml": jQuery.parseXML - }, - - // For options that shouldn't be deep extended: - // you can add your own custom options here if - // and when you create one that shouldn't be - // deep extended (see ajaxExtend) - flatOptions: { - url: true, - context: true - } - }, - - // Creates a full fledged settings object into target - // with both ajaxSettings and settings fields. - // If target is omitted, writes into ajaxSettings. - ajaxSetup: function( target, settings ) { - return settings ? - - // Building a settings object - ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : - - // Extending ajaxSettings - ajaxExtend( jQuery.ajaxSettings, target ); - }, - - ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), - ajaxTransport: addToPrefiltersOrTransports( transports ), - - // Main method - ajax: function( url, options ) { - - // If url is an object, simulate pre-1.5 signature - if ( typeof url === "object" ) { - options = url; - url = undefined; - } - - // Force options to be an object - options = options || {}; - - var transport, - - // URL without anti-cache param - cacheURL, - - // Response headers - responseHeadersString, - responseHeaders, - - // timeout handle - timeoutTimer, - - // Url cleanup var - urlAnchor, - - // Request state (becomes false upon send and true upon completion) - completed, - - // To know if global events are to be dispatched - fireGlobals, - - // Loop variable - i, - - // uncached part of the url - uncached, - - // Create the final options object - s = jQuery.ajaxSetup( {}, options ), - - // Callbacks context - callbackContext = s.context || s, - - // Context for global events is callbackContext if it is a DOM node or jQuery collection - globalEventContext = s.context && - ( callbackContext.nodeType || callbackContext.jquery ) ? - jQuery( callbackContext ) : - jQuery.event, - - // Deferreds - deferred = jQuery.Deferred(), - completeDeferred = jQuery.Callbacks( "once memory" ), - - // Status-dependent callbacks - statusCode = s.statusCode || {}, - - // Headers (they are sent all at once) - requestHeaders = {}, - requestHeadersNames = {}, - - // Default abort message - strAbort = "canceled", - - // Fake xhr - jqXHR = { - readyState: 0, - - // Builds headers hashtable if needed - getResponseHeader: function( key ) { - var match; - if ( completed ) { - if ( !responseHeaders ) { - responseHeaders = {}; - while ( ( match = rheaders.exec( responseHeadersString ) ) ) { - responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ]; - } - } - match = responseHeaders[ key.toLowerCase() ]; - } - return match == null ? null : match; - }, - - // Raw string - getAllResponseHeaders: function() { - return completed ? responseHeadersString : null; - }, - - // Caches the header - setRequestHeader: function( name, value ) { - if ( completed == null ) { - name = requestHeadersNames[ name.toLowerCase() ] = - requestHeadersNames[ name.toLowerCase() ] || name; - requestHeaders[ name ] = value; - } - return this; - }, - - // Overrides response content-type header - overrideMimeType: function( type ) { - if ( completed == null ) { - s.mimeType = type; - } - return this; - }, - - // Status-dependent callbacks - statusCode: function( map ) { - var code; - if ( map ) { - if ( completed ) { - - // Execute the appropriate callbacks - jqXHR.always( map[ jqXHR.status ] ); - } else { - - // Lazy-add the new callbacks in a way that preserves old ones - for ( code in map ) { - statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; - } - } - } - return this; - }, - - // Cancel the request - abort: function( statusText ) { - var finalText = statusText || strAbort; - if ( transport ) { - transport.abort( finalText ); - } - done( 0, finalText ); - return this; - } - }; - - // Attach deferreds - deferred.promise( jqXHR ); - - // Add protocol if not provided (prefilters might expect it) - // Handle falsy url in the settings object (#10093: consistency with old signature) - // We also use the url parameter if available - s.url = ( ( url || s.url || location.href ) + "" ) - .replace( rprotocol, location.protocol + "//" ); - - // Alias method option to type as per ticket #12004 - s.type = options.method || options.type || s.method || s.type; - - // Extract dataTypes list - s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; - - // A cross-domain request is in order when the origin doesn't match the current origin. - if ( s.crossDomain == null ) { - urlAnchor = document.createElement( "a" ); - - // Support: IE <=8 - 11, Edge 12 - 13 - // IE throws exception on accessing the href property if url is malformed, - // e.g. http://example.com:80x/ - try { - urlAnchor.href = s.url; - - // Support: IE <=8 - 11 only - // Anchor's host property isn't correctly set when s.url is relative - urlAnchor.href = urlAnchor.href; - s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== - urlAnchor.protocol + "//" + urlAnchor.host; - } catch ( e ) { - - // If there is an error parsing the URL, assume it is crossDomain, - // it can be rejected by the transport if it is invalid - s.crossDomain = true; - } - } - - // Convert data if not already a string - if ( s.data && s.processData && typeof s.data !== "string" ) { - s.data = jQuery.param( s.data, s.traditional ); - } - - // Apply prefilters - inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); - - // If request was aborted inside a prefilter, stop there - if ( completed ) { - return jqXHR; - } - - // We can fire global events as of now if asked to - // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) - fireGlobals = jQuery.event && s.global; - - // Watch for a new set of requests - if ( fireGlobals && jQuery.active++ === 0 ) { - jQuery.event.trigger( "ajaxStart" ); - } - - // Uppercase the type - s.type = s.type.toUpperCase(); - - // Determine if request has content - s.hasContent = !rnoContent.test( s.type ); - - // Save the URL in case we're toying with the If-Modified-Since - // and/or If-None-Match header later on - // Remove hash to simplify url manipulation - cacheURL = s.url.replace( rhash, "" ); - - // More options handling for requests with no content - if ( !s.hasContent ) { - - // Remember the hash so we can put it back - uncached = s.url.slice( cacheURL.length ); - - // If data is available, append data to url - if ( s.data ) { - cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; - - // #9682: remove data so that it's not used in an eventual retry - delete s.data; - } - - // Add or update anti-cache param if needed - if ( s.cache === false ) { - cacheURL = cacheURL.replace( rantiCache, "$1" ); - uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached; - } - - // Put hash and anti-cache on the URL that will be requested (gh-1732) - s.url = cacheURL + uncached; - - // Change '%20' to '+' if this is encoded form body content (gh-2658) - } else if ( s.data && s.processData && - ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { - s.data = s.data.replace( r20, "+" ); - } - - // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. - if ( s.ifModified ) { - if ( jQuery.lastModified[ cacheURL ] ) { - jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); - } - if ( jQuery.etag[ cacheURL ] ) { - jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); - } - } - - // Set the correct header, if data is being sent - if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { - jqXHR.setRequestHeader( "Content-Type", s.contentType ); - } - - // Set the Accepts header for the server, depending on the dataType - jqXHR.setRequestHeader( - "Accept", - s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? - s.accepts[ s.dataTypes[ 0 ] ] + - ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : - s.accepts[ "*" ] - ); - - // Check for headers option - for ( i in s.headers ) { - jqXHR.setRequestHeader( i, s.headers[ i ] ); - } - - // Allow custom headers/mimetypes and early abort - if ( s.beforeSend && - ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { - - // Abort if not done already and return - return jqXHR.abort(); - } - - // Aborting is no longer a cancellation - strAbort = "abort"; - - // Install callbacks on deferreds - completeDeferred.add( s.complete ); - jqXHR.done( s.success ); - jqXHR.fail( s.error ); - - // Get transport - transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); - - // If no transport, we auto-abort - if ( !transport ) { - done( -1, "No Transport" ); - } else { - jqXHR.readyState = 1; - - // Send global event - if ( fireGlobals ) { - globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); - } - - // If request was aborted inside ajaxSend, stop there - if ( completed ) { - return jqXHR; - } - - // Timeout - if ( s.async && s.timeout > 0 ) { - timeoutTimer = window.setTimeout( function() { - jqXHR.abort( "timeout" ); - }, s.timeout ); - } - - try { - completed = false; - transport.send( requestHeaders, done ); - } catch ( e ) { - - // Rethrow post-completion exceptions - if ( completed ) { - throw e; - } - - // Propagate others as results - done( -1, e ); - } - } - - // Callback for when everything is done - function done( status, nativeStatusText, responses, headers ) { - var isSuccess, success, error, response, modified, - statusText = nativeStatusText; - - // Ignore repeat invocations - if ( completed ) { - return; - } - - completed = true; - - // Clear timeout if it exists - if ( timeoutTimer ) { - window.clearTimeout( timeoutTimer ); - } - - // Dereference transport for early garbage collection - // (no matter how long the jqXHR object will be used) - transport = undefined; - - // Cache response headers - responseHeadersString = headers || ""; - - // Set readyState - jqXHR.readyState = status > 0 ? 4 : 0; - - // Determine if successful - isSuccess = status >= 200 && status < 300 || status === 304; - - // Get response data - if ( responses ) { - response = ajaxHandleResponses( s, jqXHR, responses ); - } - - // Convert no matter what (that way responseXXX fields are always set) - response = ajaxConvert( s, response, jqXHR, isSuccess ); - - // If successful, handle type chaining - if ( isSuccess ) { - - // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. - if ( s.ifModified ) { - modified = jqXHR.getResponseHeader( "Last-Modified" ); - if ( modified ) { - jQuery.lastModified[ cacheURL ] = modified; - } - modified = jqXHR.getResponseHeader( "etag" ); - if ( modified ) { - jQuery.etag[ cacheURL ] = modified; - } - } - - // if no content - if ( status === 204 || s.type === "HEAD" ) { - statusText = "nocontent"; - - // if not modified - } else if ( status === 304 ) { - statusText = "notmodified"; - - // If we have data, let's convert it - } else { - statusText = response.state; - success = response.data; - error = response.error; - isSuccess = !error; - } - } else { - - // Extract error from statusText and normalize for non-aborts - error = statusText; - if ( status || !statusText ) { - statusText = "error"; - if ( status < 0 ) { - status = 0; - } - } - } - - // Set data for the fake xhr object - jqXHR.status = status; - jqXHR.statusText = ( nativeStatusText || statusText ) + ""; - - // Success/Error - if ( isSuccess ) { - deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); - } else { - deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); - } - - // Status-dependent callbacks - jqXHR.statusCode( statusCode ); - statusCode = undefined; - - if ( fireGlobals ) { - globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", - [ jqXHR, s, isSuccess ? success : error ] ); - } - - // Complete - completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); - - if ( fireGlobals ) { - globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); - - // Handle the global AJAX counter - if ( !( --jQuery.active ) ) { - jQuery.event.trigger( "ajaxStop" ); - } - } - } - - return jqXHR; - }, - - getJSON: function( url, data, callback ) { - return jQuery.get( url, data, callback, "json" ); - }, - - getScript: function( url, callback ) { - return jQuery.get( url, undefined, callback, "script" ); - } -} ); - -jQuery.each( [ "get", "post" ], function( i, method ) { - jQuery[ method ] = function( url, data, callback, type ) { - - // Shift arguments if data argument was omitted - if ( jQuery.isFunction( data ) ) { - type = type || callback; - callback = data; - data = undefined; - } - - // The url can be an options object (which then must have .url) - return jQuery.ajax( jQuery.extend( { - url: url, - type: method, - dataType: type, - data: data, - success: callback - }, jQuery.isPlainObject( url ) && url ) ); - }; -} ); - - -jQuery._evalUrl = function( url ) { - return jQuery.ajax( { - url: url, - - // Make this explicit, since user can override this through ajaxSetup (#11264) - type: "GET", - dataType: "script", - cache: true, - async: false, - global: false, - "throws": true - } ); -}; - - -jQuery.fn.extend( { - wrapAll: function( html ) { - var wrap; - - if ( this[ 0 ] ) { - if ( jQuery.isFunction( html ) ) { - html = html.call( this[ 0 ] ); - } - - // The elements to wrap the target around - wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); - - if ( this[ 0 ].parentNode ) { - wrap.insertBefore( this[ 0 ] ); - } - - wrap.map( function() { - var elem = this; - - while ( elem.firstElementChild ) { - elem = elem.firstElementChild; - } - - return elem; - } ).append( this ); - } - - return this; - }, - - wrapInner: function( html ) { - if ( jQuery.isFunction( html ) ) { - return this.each( function( i ) { - jQuery( this ).wrapInner( html.call( this, i ) ); - } ); - } - - return this.each( function() { - var self = jQuery( this ), - contents = self.contents(); - - if ( contents.length ) { - contents.wrapAll( html ); - - } else { - self.append( html ); - } - } ); - }, - - wrap: function( html ) { - var isFunction = jQuery.isFunction( html ); - - return this.each( function( i ) { - jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html ); - } ); - }, - - unwrap: function( selector ) { - this.parent( selector ).not( "body" ).each( function() { - jQuery( this ).replaceWith( this.childNodes ); - } ); - return this; - } -} ); - - -jQuery.expr.pseudos.hidden = function( elem ) { - return !jQuery.expr.pseudos.visible( elem ); -}; -jQuery.expr.pseudos.visible = function( elem ) { - return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); -}; - - - - -jQuery.ajaxSettings.xhr = function() { - try { - return new window.XMLHttpRequest(); - } catch ( e ) {} -}; - -var xhrSuccessStatus = { - - // File protocol always yields status code 0, assume 200 - 0: 200, - - // Support: IE <=9 only - // #1450: sometimes IE returns 1223 when it should be 204 - 1223: 204 - }, - xhrSupported = jQuery.ajaxSettings.xhr(); - -support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); -support.ajax = xhrSupported = !!xhrSupported; - -jQuery.ajaxTransport( function( options ) { - var callback, errorCallback; - - // Cross domain only allowed if supported through XMLHttpRequest - if ( support.cors || xhrSupported && !options.crossDomain ) { - return { - send: function( headers, complete ) { - var i, - xhr = options.xhr(); - - xhr.open( - options.type, - options.url, - options.async, - options.username, - options.password - ); - - // Apply custom fields if provided - if ( options.xhrFields ) { - for ( i in options.xhrFields ) { - xhr[ i ] = options.xhrFields[ i ]; - } - } - - // Override mime type if needed - if ( options.mimeType && xhr.overrideMimeType ) { - xhr.overrideMimeType( options.mimeType ); - } - - // X-Requested-With header - // For cross-domain requests, seeing as conditions for a preflight are - // akin to a jigsaw puzzle, we simply never set it to be sure. - // (it can always be set on a per-request basis or even using ajaxSetup) - // For same-domain requests, won't change header if already provided. - if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { - headers[ "X-Requested-With" ] = "XMLHttpRequest"; - } - - // Set headers - for ( i in headers ) { - xhr.setRequestHeader( i, headers[ i ] ); - } - - // Callback - callback = function( type ) { - return function() { - if ( callback ) { - callback = errorCallback = xhr.onload = - xhr.onerror = xhr.onabort = xhr.onreadystatechange = null; - - if ( type === "abort" ) { - xhr.abort(); - } else if ( type === "error" ) { - - // Support: IE <=9 only - // On a manual native abort, IE9 throws - // errors on any property access that is not readyState - if ( typeof xhr.status !== "number" ) { - complete( 0, "error" ); - } else { - complete( - - // File: protocol always yields status 0; see #8605, #14207 - xhr.status, - xhr.statusText - ); - } - } else { - complete( - xhrSuccessStatus[ xhr.status ] || xhr.status, - xhr.statusText, - - // Support: IE <=9 only - // IE9 has no XHR2 but throws on binary (trac-11426) - // For XHR2 non-text, let the caller handle it (gh-2498) - ( xhr.responseType || "text" ) !== "text" || - typeof xhr.responseText !== "string" ? - { binary: xhr.response } : - { text: xhr.responseText }, - xhr.getAllResponseHeaders() - ); - } - } - }; - }; - - // Listen to events - xhr.onload = callback(); - errorCallback = xhr.onerror = callback( "error" ); - - // Support: IE 9 only - // Use onreadystatechange to replace onabort - // to handle uncaught aborts - if ( xhr.onabort !== undefined ) { - xhr.onabort = errorCallback; - } else { - xhr.onreadystatechange = function() { - - // Check readyState before timeout as it changes - if ( xhr.readyState === 4 ) { - - // Allow onerror to be called first, - // but that will not handle a native abort - // Also, save errorCallback to a variable - // as xhr.onerror cannot be accessed - window.setTimeout( function() { - if ( callback ) { - errorCallback(); - } - } ); - } - }; - } - - // Create the abort callback - callback = callback( "abort" ); - - try { - - // Do send the request (this may raise an exception) - xhr.send( options.hasContent && options.data || null ); - } catch ( e ) { - - // #14683: Only rethrow if this hasn't been notified as an error yet - if ( callback ) { - throw e; - } - } - }, - - abort: function() { - if ( callback ) { - callback(); - } - } - }; - } -} ); - - - - -// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) -jQuery.ajaxPrefilter( function( s ) { - if ( s.crossDomain ) { - s.contents.script = false; - } -} ); - -// Install script dataType -jQuery.ajaxSetup( { - accepts: { - script: "text/javascript, application/javascript, " + - "application/ecmascript, application/x-ecmascript" - }, - contents: { - script: /\b(?:java|ecma)script\b/ - }, - converters: { - "text script": function( text ) { - jQuery.globalEval( text ); - return text; - } - } -} ); - -// Handle cache's special case and crossDomain -jQuery.ajaxPrefilter( "script", function( s ) { - if ( s.cache === undefined ) { - s.cache = false; - } - if ( s.crossDomain ) { - s.type = "GET"; - } -} ); - -// Bind script tag hack transport -jQuery.ajaxTransport( "script", function( s ) { - - // This transport only deals with cross domain requests - if ( s.crossDomain ) { - var script, callback; - return { - send: function( _, complete ) { - script = jQuery( " - - - - - - - - - - - - - - - -
-
-
-
- - -

Index

- -
- -
- - -
-
-
- -
-
- - - - - - - \ No newline at end of file diff --git a/src/doc/user/sphinx/_build/html/objects.inv b/src/doc/user/sphinx/_build/html/objects.inv deleted file mode 100644 index f540b7814a4482da325795b999a8fb83ef828b31..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 236 zcmY#Z2rkIT%&Sny%qvUHE6FdaR47X=D$dN$Q!wIERtPA{&q_@$u~H~XP0r8B0g8k{ zWUUko^^8pQ3_*%QGE#x^xrv#1DXB#Y`DqFz8JWcjX_+~x3P3tJKewPLwYWGnMWM7f zGcR4CDkn2ZkE`OAxBuDGXS_Yv259JcZan4b<8?Ohf@z3Hd)KSfDNmkhR5ZAi#_F)bH diff --git a/src/doc/user/sphinx/_build/html/search.html b/src/doc/user/sphinx/_build/html/search.html deleted file mode 100644 index 5beea0e5..00000000 --- a/src/doc/user/sphinx/_build/html/search.html +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - Search — recoll 1.25.12 documentation - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
- -

Search

-
- -

- Please activate JavaScript to enable the search - functionality. -

-
-

- From here you can search these documents. Enter your search - words into the box below and click "search". Note that the search - function will automatically search for all of the words. Pages - containing fewer words won't appear in the result list. -

-
- - - -
- -
- -
- -
-
-
- -
-
- - - - - - - \ No newline at end of file diff --git a/src/doc/user/sphinx/_build/html/searchindex.js b/src/doc/user/sphinx/_build/html/searchindex.js deleted file mode 100644 index 89f4424d..00000000 --- a/src/doc/user/sphinx/_build/html/searchindex.js +++ /dev/null @@ -1 +0,0 @@ -Search.setIndex({envversion:50,filenames:["usermanual"],objects:{},objnames:{},objtypes:{},terms:{"00readme":0,"10k":0,"11p1":0,"1e12":0,"1e3":0,"1e6":0,"1e9":0,"20mn":0,"30am":0,"5e6":0,"64x64":0,"\u00dfss":0,"\u00e6ae":0,"\u0153oe":0,"\ufb00ff":0,"\ufb01fi":0,"\ufb02fl":0,"abstract":0,"boolean":0,"break":0,"byte":0,"class":0,"else":0,"export":0,"final":0,"function":0,"int":0,"long":0,"mat\u00e9":0,"null":0,"public":0,"r\u00e9sum\u00e9":0,"return":0,"sak\u00e9":0,"short":0,"switch":0,"true":0,"var":0,"while":0,__init__:0,__iter__:0,abandon:0,abbrevi:0,abc:0,abil:0,abiword:0,abl:0,abov:0,abrrevi:0,absenc:0,absent:0,absolut:0,abtract:0,accent:0,accept:0,accommod:0,accomplish:0,accord:0,account:0,accumul:0,accur:0,acess:0,achiev:0,acrobat:0,across:0,action:0,activ:0,activat:0,actual:0,actualli:0,adapt:0,add:0,addclaus:0,addit:0,addition:0,addon:0,addorupdat:0,address:0,adequ:0,adjac:0,administr:0,advantag:0,advers:0,afford:0,after:0,again:0,against:0,agent:0,aggreg:0,ago:0,ajust:0,algorithm:0,alia:0,alias:0,align:0,aliteratt:0,all:0,alliter:0,allow:0,almost:0,alon:0,along:0,alphabet:0,alreadi:0,also:0,alter:0,alterc:0,altern:0,alwai:0,among:0,amount:0,amp:0,anacron:0,analyz:0,anchor:0,and_not:0,ani:0,anim:0,anoth:0,another:0,antiword:0,any:0,anyth:0,anywai:0,anywher:0,apart:0,apertur:0,app:0,appar:0,apparten:0,appdata:0,appear:0,append:0,appli:0,applic:0,applicat:0,approach:0,appropri:0,approxim:0,apt:0,archiv:0,area:0,argument:0,around:0,arrai:0,arrays:0,arrow:0,arrowup:0,articl:0,ascend:0,ascii:0,asian:0,ask:0,aspdict:0,aspel:0,aspell:0,aspell_prog:0,aspelladdcreateparam:0,aspelldicdir:0,aspellkeepstderr:0,aspelllanguag:0,assign:0,associ:0,assum:0,astringlist:0,athlon:0,attempt:0,attr1:0,audio:0,augment:0,author:0,auto:0,autocasesen:0,autocomplet:0,autoconf:0,autoconfigur:0,autodiacsen:0,autogen:0,automak:0,autophras:0,autostart:0,auxiliari:0,avail:0,averag:0,avoid:0,awai:0,awar:0,awk:0,back:0,backend:0,background:0,backport:0,backslash:0,backslashaslett:0,backup:0,bad:0,balzac:0,bar:0,bare:0,base64:0,base:0,basenam:0,basi:0,basic:0,batch:0,bateaux:0,beagl:0,beatl:0,becam:0,becaus:0,becom:0,been:0,befor:0,begin:0,behav:0,behaviour:0,belong:0,below:0,besid:0,best:0,better:0,between:0,beyond:0,bgcolor:0,bgl:0,bibl:0,bibtex:0,bigger:0,bin:0,bind:0,bison:0,bit:0,bla:0,blabla:0,blank:0,blob:0,blobapp:0,blobview:0,blue:0,bodi:0,bogu:0,boilerpl:0,book:0,boost:0,both:0,bottom:0,box:0,broad:0,broadli:0,broken:0,brought:0,brown:0,brows:0,browser:0,bug:0,built:0,button:0,bye:0,cach:0,cachedir:0,call:0,caller:0,came:0,camelcas:0,can:0,cancel:0,candid:0,cannot:0,canon:0,cap:0,capabl:0,capac:0,capit:0,caption:0,card:0,care:0,carri:0,casesen:0,casual:0,cat:0,categori:0,caus:0,cdrom:0,central:0,certain:0,certainli:0,cfn:0,chanc:0,chang:0,chapter:0,charact:0,charg:0,charset:0,chass:0,chdir:0,check:0,checkbox:0,checkbutton:0,checkneedretryindexscript:0,checkpoint:0,checksum:0,chert:0,children:0,chines:0,chm:0,chmlib:0,chmod:0,choic:0,choos:0,chose:0,chosen:0,circumst:0,citizenship:0,cjk:0,cjkngramlen:0,claim:0,classic:0,classif:0,classifi:0,clean:0,clear:0,clearer:0,client:0,clipboard:0,clock:0,clone:0,close:0,cmd:0,cmdoutputsconf:0,cnt:0,code:0,coll:0,colon:0,color:0,column:0,com:0,combin:0,come:0,comma:0,comment:0,common:0,commonli:0,commun:0,compact:0,compani:0,compar:0,comparison:0,compil:0,complain:0,complement:0,complet:0,complic:0,compos:0,compound:0,compress:0,compressedfilemaxkb:0,compt:0,comput:0,concaten:0,conced:0,conceiv:0,concern:0,concurr:0,condit:0,confdir:0,confidenti:0,config:0,configdir:0,confus:0,conjunct:0,connect:0,consecut:0,consequ:0,conserv:0,consist:0,consol:0,constant:0,constrain:0,constraint:0,construct:0,constructc:0,constructio:0,consum:0,conta:0,containerfilenam:0,context:0,contextword:0,continu:0,contrari:0,control:0,conveni:0,convers:0,convert:0,cooper:0,core:0,correct:0,correspond:0,corrupt:0,cost:0,costli:0,could:0,count:0,counter:0,counterproduct:0,coupl:0,cours:0,cover:0,cowork:0,cpp:0,cpu:0,crash:0,creation:0,criteria:0,crontab:0,css:0,csv:0,ctime:0,ctl:0,ctrl:0,cumbersom:0,cun:0,curidxconfdir:0,current:0,cursor:0,customis:0,customiz:0,cut:0,cutoff:0,daemlogfilenam:0,daemloglevel:0,daemskippedpath:0,dai:0,dark:0,databas:0,dataset:0,date:0,dbdir:0,dbyte:0,ddthh:0,deactiv:0,deal:0,debian:0,debug:0,decid:0,decim:0,decod:0,decompos:0,decomposit:0,decompress:0,decreas:0,dedic:0,dedupl:0,deep:0,deeper:0,def:0,defaultcharset:0,defin:0,definit:0,defunct:0,degrad:0,dehyphen:0,delai:0,delet:0,demonstr:0,depend:0,depth:0,deriv:0,descend:0,describ:0,descript:0,design:0,desir:0,destin:0,destroi:0,detach:0,detect:0,determin:0,detex:0,develop:0,diacsen:0,diaeresi:0,dialog:0,dict:0,dictionari:0,did:0,diesel:0,differ:0,differenti:0,difficult:0,difficulti:0,diminish:0,dir1:0,dir2:0,dir3:0,dir:0,dira:0,dirb:0,direct:0,directli:0,directori:0,dirti:0,disabl:0,discard:0,discret:0,discrimin:0,disk:0,display:0,distanc:0,distribut:0,disturb:0,div:0,dive:0,divid:0,djvu:0,djvulibr:0,djvuse:0,djvutxt:0,dmtime:0,doc:0,docbook:0,docdata:0,docdir:0,dock:0,docnum:0,docx:0,doe:0,domain:0,don:0,done:0,dot:0,doubl:0,doubt:0,down:0,download:0,dozen:0,dpkg:0,drag:0,drawback:0,drive:0,drop:0,dropbox:0,dropdown:0,due:0,dump:0,dup:0,dure:0,dvi:0,dvip:0,dynam:0,e0e0e0:0,each:0,earlier:0,easi:0,easier:0,easili:0,east:0,eat:0,ebook:0,echo:0,edit:0,edite:0,editor:0,effect:0,effici:0,effort:0,either:0,elaps:0,elif:0,elimin:0,ellipsi:0,els:0,elsewher:0,email:0,emb:0,embed:0,embryon:0,empti:0,emulat:0,enabl:0,encapsul:0,enclos:0,encod:0,encode:0,encodeuricompon:0,encount:0,end:0,endmatch:0,engin:0,english:0,enospc:0,enough:0,ensur:0,enter:0,entere:0,entir:0,entiti:0,entri:0,entry:0,env:0,epub:0,equal:0,equiv:0,equival:0,eras:0,erase:0,errno:0,error:0,esc:0,escap:0,escape:0,esp:0,especi:0,especial:0,essenti:0,estim:0,etc:0,eugeni:0,evalu:0,even:0,event:0,eventu:0,ever:0,everi:0,evid:0,evinc:0,evolut:0,exact:0,exactli:0,excel:0,except:0,excess:0,excl:0,exclud:0,exclude:0,excludedmimetyp:0,exclus:0,exclusion:0,exec:0,execm:0,execut:0,executesd:0,executexx:0,exempl:0,exercis:0,exhaust:0,exiftool:0,exist:0,exit:0,expand:0,expect:0,expens:0,experi:0,experiment:0,explain:0,explan:0,explicit:0,explicitli:0,expr:0,express:0,ext:0,extens:0,extra_db:0,extractor:0,extrem:0,facil:0,fact:0,factetci:0,factor:0,fail:0,fallback:0,fals:0,fam:0,faq:0,faqsandhowto:0,fashion:0,fast:0,faster:0,fatal:0,favor:0,fb2:0,fbyte:0,featur:0,fed:0,feedback:0,fetch:0,fetchmani:0,fetchon:0,fetchtext:0,few:0,ff0000:0,fieldnam:0,fields:0,fieldvalu:0,filenam:0,filesystem:0,filteringoutziparchivememb:0,filtermaxmbyt:0,filtermaxsecond:0,filtersdir:0,find_applet:0,finish:0,firefox:0,first:0,fit:0,fix:0,flag:0,fld:0,floor:0,flush:0,fmtime:0,fnm_pathname:0,fnmatch:0,focu:0,folder:0,follow:0,followlink:0,font:0,footwork:0,forc:0,foreground:0,foreign:0,forget:0,forgotten:0,form:0,former:0,found:0,four:0,fox:0,frag:0,fragbut:0,frame:0,framework:0,francoi:0,freebsd:0,freedesktop:0,freez:0,french:0,frequenc:0,frequent:0,fulli:0,further:0,futur:0,fvwm:0,gamin:0,garden:0,gather:0,gbyte:0,geometri:0,german:0,get:0,getattr:0,getbinurl:0,getgroup:0,getselect:0,getxqueri:0,git:0,given:0,glass:0,glitch:0,global:0,gnome:0,gnu:0,goal:0,goe:0,good:0,goodby:0,gram:0,grammat:0,grandet:0,great:0,group:0,grow:0,guarante:0,guess:0,guid:0,guidelin:0,guifilt:0,hack:0,had:0,hand:0,handl:0,happen:0,happili:0,hard:0,hardship:0,hardwar:0,hasextract:0,hash:0,have:0,head:0,header:0,hello:0,help:0,helper:0,helpfulgui:0,here:0,heurist:0,hidden:0,hide:0,hierarch:0,hierarchi:0,high:0,higher:0,highest:0,highli:0,highlight:0,hint:0,histor:0,hit:0,hoc:0,hold:0,home:0,hood:0,hopefulli:0,horizont:0,hour:0,hover:0,howev:0,href:0,html:0,http:0,huge:0,human:0,ibm:0,icalendar:0,icon:0,iconsdir:0,iconv:0,ics:0,idea:0,ident:0,identif:0,identifi:0,idoctofil:0,idx:0,idxabsmlen:0,idxflushmb:0,idxlogfilenam:0,idxloglevel:0,idxmetastoredlen:0,idxrundir:0,idxstatu:0,idxstatusfil:0,idxtexttruncatelen:0,idxthread:0,ignor:0,illeg:0,ilur1:0,ilur:0,imag:0,imagin:0,imbric:0,img:0,immedi:0,impati:0,implement:0,impli:0,implicit:0,implicitli:0,important:0,importantli:0,impos:0,imposs:0,improv:0,inact:0,incant:0,includ:0,include:0,incompat:0,incomplet:0,inconsist:0,inconveni:0,incorrect:0,increas:0,increment:0,indefinit:0,indent:0,independ:0,independantli:0,indexallfilenam:0,indexedmimetyp:0,indexing:0,indexstemminglanguag:0,indexstoredoctext:0,indexstripchar:0,indic:0,individu:0,ineffici:0,inexist:0,inferior:0,infinit:0,inflect:0,influenc:0,inform:0,inherit:0,init:0,initi:0,initial:0,inotifi:0,inotify_add_watch:0,insensit:0,insert:0,instal:0,instanc:0,instant:0,instantli:0,instead:0,instruct:0,insuffici:0,integ:0,intellig:0,interact:0,interest:0,intermedi:0,intermediari:0,intern:0,internal:0,internet:0,interpret:0,interrupt:0,interv:0,introduc:0,invalid:0,invent:0,invert:0,invoc:0,involv:0,ionic:0,ipath:0,irrelev:0,ishtml:0,iso8601:0,iso:0,issu:0,item:0,itself:0,japanes:0,javascript:0,jean:0,jessi:0,job:0,john:0,just:0,karaok:0,keep:0,kei:0,kept:0,keyboard:0,keystrok:0,keyword:0,kill:0,kind:0,know:0,known:0,konqueror:0,korean:0,krunner:0,kword:0,label:0,lame:0,lang:0,larg:0,last:0,late:0,latest:0,latter:0,launch:0,launcher:0,layer:0,lc_all:0,lc_ctype:0,lead:0,least:0,leav:0,left:0,len:0,length:0,lennon:0,lesbonscompt:0,less:0,let:0,letter:0,level:0,lib:0,libaspel:0,libc:0,libiconv:0,libpst:0,librari:0,libreoffic:0,libtool:0,libwnck:0,libwpd:0,libxslt:0,light:0,like:0,limit:0,linear:0,link:0,linux:0,listbox:0,liter:0,littl:0,live:0,load:0,local:0,localfield:0,lock:0,log:0,logfilenam:0,logic:0,loglevel:0,longer:0,look:0,loop:0,lose:0,lot:0,low:0,lower:0,lowercas:0,lowest:0,lyx:0,mac:0,machin:0,made:0,magic:0,mai:0,mail:0,maildefcharset:0,mailmytag:0,mainli:0,mainten:0,major:0,make:0,makedocabstract:0,makefil:0,makesig:0,man:0,manag:0,mani:0,map:0,mare:0,margin:0,markup:0,match:0,match_typ:0,mate:0,matrch:0,matter:0,matur:0,max:0,max_queued_ev:0,max_user_inst:0,max_user_watch:0,maxchar:0,maxfsoccuppc:0,maximum:0,maxlen:0,maxtermexpand:0,maxtermlength:0,maxxapianclaus:0,mayb:0,mbox:0,mboxcach:0,mboxcachedir:0,mboxcacheminmb:0,md5:0,mean:0,meaning:0,meaningfulli:0,mechan:0,media:0,medium:0,megabyt:0,member:0,membermaxkb:0,memor:0,memori:0,merg:0,messag:0,meta:0,metadata:0,metadatacmd:0,metadatacmds:0,metafix:0,metahead:0,method:0,mhmboxquirk:0,microsoft:0,middl:0,midi:0,might:0,mild:0,mime:0,mime_typ:0,mimehtml:0,mimetyp:0,mind:0,minim:0,minimum:0,minor:0,misc:0,mispel:0,miss:0,misspel:0,mistak:0,mistakenli:0,mistyp:0,mitig:0,mix:0,mkdir:0,model:0,modern:0,modif:0,modifierchar:0,moment:0,monauxinterv:0,mondelaypattern:0,monioniceclass:0,monioniceclassdata:0,monitor:0,monitordir:0,monixinterv:0,monster:0,month:0,morn:0,most:0,mostli:0,mount:0,movabl:0,move:0,mozilla:0,mp3:0,mpeg:0,msword:0,mtime:0,mtype:0,much:0,multi:0,multilevel:0,multimedia:0,multipli:0,multiprocessor:0,multithread:0,multitud:0,must:0,mutagen:0,mutex:0,mutual:0,mydata:0,mydoc:0,myfield:0,myfile1:0,myfile2:0,myfirstscript:0,mylogin:0,myscript:0,mysql:0,name:0,narrow:0,narrowli:0,nativ:0,natur:0,nautiqu:0,nbsp:0,necess:0,necessari:0,necessarili:0,need:0,needupdat:0,neg:0,negat:0,neglig:0,net:0,never:0,nevertheless:0,newer:0,newest:0,newlin:0,next:0,nfs:0,nice:0,nicer:0,nicknam:0,night:0,nightli:0,nls:0,noaspel:0,nobodi:0,nocjk:0,nocontentsuffix:0,noindex:0,nomd5typ:0,none:0,nonumb:0,nopict:0,nor:0,normal:0,note:0,noth:0,notifi:0,notion:0,nouncompforviewmt:0,now:0,nowalkfn:0,nowrap:0,noxattrfield:0,nre:0,nuanc:0,nutshel:0,o10:0,object:0,observ:0,obsolet:0,obtain:0,obvious:0,occup:0,occur:0,occurr:0,ocrpdf:0,ocrpdflang:0,odt:0,off:0,offer:0,offic:0,offset:0,often:0,ogg:0,oil:0,okular:0,old:0,older:0,oldest:0,omnipot:0,onc:0,once:0,ondblclick:0,one:0,onli:0,onlin:0,only:0,onto:0,oofic:0,opaqu:0,open:0,opendoc:0,opendocu:0,openoffic:0,openxml:0,oper:0,oppos:0,optim:0,option:0,order:0,ordinari:0,org:0,orgidxconfdir:0,origin:0,otherwis:0,our:0,out:0,outdat:0,outfil:0,outsid:0,over:0,overhead:0,overrid:0,overridden:0,overriden:0,own:0,owner:0,p1y2m:0,p2d:0,p2y:0,packet:0,pagedown:0,pagep:0,pageup:0,pair:0,panel:0,parallel:0,parent:0,parent_udi:0,parenthes:0,pars:0,part:0,partial:0,particular:0,particularli:0,partit:0,pass:0,past:0,patch:0,pattern:0,pdfattach:0,pdfextrameta:0,pdfextrametafix:0,pdfinfo:0,pdfocr:0,pdfocrlang:0,pdftk:0,pdftoppm:0,pdftotext:0,penal:0,pentium:0,peopl:0,per:0,percentag:0,perfectli:0,perhap:0,periodic:0,perl:0,perman:0,permiss:0,permit:0,persist:0,person:0,phase:0,phonet:0,php:0,physic:0,pic:0,pick:0,pictur:0,piec:0,pipelin:0,pixel:0,place:0,plain:0,platform:0,plausibl:0,pleas:0,plugin:0,plural:0,png:0,po10:0,point:0,pointer:0,pop:0,poppler:0,popul:0,popup:0,port:0,portabl:0,pose:0,posit:0,possibl:0,postscript:0,potato:0,potenti:0,power:0,powerpoint:0,practic:0,practis:0,pre:0,preced:0,precis:0,precook:0,predefin:0,prefer:0,prefix:0,prejudic:0,prepar:0,prepend:0,preprocess:0,present:0,preserv:0,press:0,pression:0,pretti:0,prevent:0,previous:0,pride:0,primari:0,prime:0,primit:0,print:0,printf:0,prior:0,prioriti:0,probabilist:0,probabl:0,problem:0,proc:0,proce:0,procedur:0,processor:0,processwebqueu:0,produc:0,progress:0,project:0,projet:0,promin:0,proper:0,properli:0,properti:0,propos:0,protect:0,protest:0,protocol:0,proven:0,provid:0,pstotext:0,psxtcl:0,ptrans:0,punctat:0,punctuat:0,pure:0,purg:0,purpos:0,puzzl:0,pwd:0,pychm:0,python2:0,python3:0,pythonx:0,qdoc:0,qss:0,qstring:0,qtconfig:0,qtextbrows:0,qtgui:0,qtp:0,quadrat:0,quadri:0,qualifi:0,qualiti:0,query_str:0,queryalias:0,question:0,queue:0,quick:0,quirk:0,quit:0,quot:0,qzeitgeist:0,radic:0,radio:0,radiobutton:0,ram:0,random:0,rank:0,rapidli:0,rar:0,rare:0,rarfil:0,rate:0,rather:0,ratio:0,raw:0,rclapps:0,rclaptg:0,rclaudio:0,rclbe:0,rclblob:0,rclcat:0,rclchm:0,rcldb:0,rcldoc:0,rclexec1:0,rclexecm:0,rclgenxslt:0,rclimg:0,rclmatch:0,rclmbox:0,rclmon:0,rclmulti1:0,rclmulti:0,rclmultixx:0,rclogg:0,rclp:0,rclpdf:0,rclrtf:0,rcltracem:0,rcltxtline:0,rclversion:0,rclzip:0,reach:0,read:0,readi:0,readonli:0,readpst:0,realist:0,realiti:0,realli:0,reason:0,rebuild:0,rebuilt:0,receiv:0,recent:0,recipi:0,recogn:0,recognit:0,recoll_active_extra_dbs:0,recoll_applet:0,recoll_confdir:0,recoll_confmid:0,recoll_conftop:0,recoll_datadir:0,recoll_extra_dbs:0,recoll_filter_forpreview:0,recoll_filter_maxmemberkb:0,recoll_filtersdir:0,recoll_noindex:0,recoll_tesseract_lang:0,recoll_tmpdir:0,recollconf:0,recolldata:0,recollglob:0,recollgui:0,recollhelperpath:0,recollindex:0,recollq:0,recollsearch:0,recolltrac:0,recollweb:0,recommend:0,reconstruct:0,record:0,recu:0,recurs:0,red:0,redefin:0,redefinit:0,reduc:0,redund:0,refer:0,refin:0,reflect:0,regard:0,regexp:0,regist:0,regular:0,regularli:0,reindex:0,rel:0,relat:0,releas:0,relev:0,reli:0,reliabl:0,remain:0,remaind:0,rememb:0,remind:0,remot:0,renam:0,render:0,repeat:0,repel:0,rephras:0,replac:0,repositori:0,request:0,requir:0,reset:0,resid:0,resiz:0,respar:0,respect:0,respons:0,rest:0,restart:0,restrict:0,resum:0,resume:0,retain:0,retri:0,retriev:0,retrospect:0,reusabl:0,revers:0,revert:0,revoir:0,rewrit:0,ringo:0,risk:0,rlimit_as:0,room:0,root:0,roughli:0,row:0,rowcount:0,rownum:0,rownumb:0,rtf:0,rule:0,safe:0,sai:0,sake:0,same:0,saver:0,scan:0,scenario:0,schedul:0,scientif:0,scope:0,score:0,scratch:0,screen:0,scribu:0,scriptnam:0,scroll:0,seamonkei:0,searchdata:0,second:0,secondari:0,section:0,sed:0,see:0,seek:0,seem:0,seen:0,segment:0,select:0,selector:0,semi:0,send:0,sens:0,sent:0,separ:0,sequenc:0,sequenti:0,seriou:0,server:0,session:0,setabstractparam:0,setattr:0,setbinurl:0,setfield:0,setrlimit:0,sett:0,setup:0,sever:0,share:0,sheet:0,shell:0,shift:0,shop:0,shorter:0,should:0,show:0,shown:0,side:0,sig:0,sigint:0,sign:0,signal:0,signatur:0,signific:0,significantli:0,sigterm:0,similar:0,simpler:0,simpli:0,simplifi:0,sinc:0,singl:0,singular:0,site:0,situat:0,size:0,skeleton:0,skip:0,skippednam:0,skippedpath:0,skippedpathsfnmpathnam:0,slack:0,slash:0,slice:0,slightli:0,slow:0,slower:0,small:0,smaller:0,smith:0,snippet:0,snippetmaxposwalk:0,softwar:0,solut:0,some:0,somedir:0,somedirectori:0,somedirnam:0,somefield:0,somelabel:0,someon:0,someoth:0,someothergui:0,someothernam:0,someterm:0,someth:0,sometim:0,somewhat:0,somewher:0,soon:0,sooner:0,sophist:0,sortbi:0,sound:0,space:0,span:0,spare:0,spec:0,specifi:0,speed:0,speller:0,split:0,spreadsheet:0,sql:0,src:0,ssd:0,sse:0,stabl:0,stack:0,stage:0,stai:0,stale:0,standard:0,startmatch:0,startup:0,stat:0,state:0,statu:0,stderr:0,stdin:0,stdout:0,stem:0,stemdb:0,stemlang:0,stemmer:0,step:0,still:0,stillanoth:0,stop:0,stopiter:0,stori:0,strang:0,stream:0,strftime:0,strictli:0,string:0,strip:0,strongli:0,structur:0,style:0,sub:0,subdirectori:0,subdocu:0,subject:0,submenu:0,subpath:0,subsearch:0,subsect:0,subsequ:0,subset:0,substitut:0,subtre:0,succe:0,success:0,successful:0,sudo:0,suffici:0,suffix:0,suppli:0,suppos:0,suppress:0,sure:0,surprisingli:0,svg:0,swap:0,swedish:0,symbol:0,syntax:0,synthes:0,synthet:0,sysctl:0,system:0,systemfilecommand:0,tailor:0,take:0,taken:0,tar:0,tarfil:0,target:0,targetmtyp:0,task:0,tast:0,tax:0,taylor:0,technic:0,tediou:0,tempconfig:0,temporari:0,ten:0,tens:0,termin:0,termmatch:0,terms:0,test:0,testmodifusemtim:0,tex:0,textextract:0,textfilemaxmb:0,textfilepagekb:0,textual:0,than:0,thei:0,them:0,themselv:0,thesam:0,think:0,third:0,those:0,though:0,three:0,threshold:0,through:0,thrqsize:0,thrtcount:0,thumb:0,thunderbird:0,tild:0,timestamp:0,titl:0,tmp:0,tmpdir:0,tmsu:0,togeth:0,toggl:0,toindex:0,too:0,took:0,toolbar:0,toolbox:0,toolchain:0,tooltip:0,top:0,topdir:0,topdirs:0,total:0,touch:0,tradit:0,trail:0,transcod:0,transfer:0,transform:0,trash:0,travers:0,treat:0,treatment:0,tree:0,tri:0,triad:0,trick:0,trigger:0,trim:0,trivial:0,troubl:0,truncat:0,tryscript:0,ttext:0,turn:0,tweak:0,twelv:0,twice:0,two:0,txt:0,typic:0,ubuntu:0,udi:0,ultim:0,umask:0,unac:0,unac_except_tran:0,unacc:0,unaccept:0,uncheck:0,uncommon:0,uncompress:0,uncrypt:0,under:0,underli:0,undesir:0,undetect:0,undisplai:0,unend:0,unexpect:0,unfortun:0,unfreez:0,unicod:0,uninterest:0,uniqu:0,uniti:0,unix:0,unknown:0,unless:0,unlik:0,unmanag:0,unmount:0,unord:0,unplug:0,unprocess:0,unrar:0,unreach:0,unreason:0,unrtf:0,unsensit:0,unstem:0,unsupport:0,untex:0,until:0,unus:0,unzip:0,upgrad:0,upmpdcli:0,upnp:0,upper:0,upward:0,uri:0,url:0,usabl:0,usage:0,usb:0,use:0,userdoc:0,usesystemfilecommand:0,usr:0,usual:0,usualli:0,utf8:0,utf:0,util:0,val1:0,val:0,valid:0,valu:0,value123:0,vari:0,variant:0,variat:0,varname:0,vector:0,verb:0,verbos:0,veri:0,vertic:0,via:0,video:0,view:0,virtual:0,visit:0,visual:0,volume1:0,volume2:0,wai:0,wait:0,walk:0,want:0,warn:0,wast:0,wear:0,webarch:0,webcach:0,webcachedir:0,webcachemaxmb:0,webdownloadsdir:0,webextens:0,webkit:0,webnautiqu:0,webqueuedir:0,webui:0,weight:0,weird:0,welcom:[],well:0,were:0,western:0,whatev:0,when:0,whenev:0,whether:0,white:0,who:0,whole:0,why:0,wide:0,widget:0,width:0,wiki:0,wild:0,wildcardpattern:0,wildli:0,win:0,wire:0,wish:0,within:0,without:0,word1:0,word2:0,word3:0,word:0,wordperfect:0,workalik:0,workaround:0,worker:0,world:0,wors:0,worth:0,would:0,wpd2html:0,wqf:0,wrap:0,wrapup:0,writabl:0,writemim:0,written:0,wvware:0,www:0,x11:0,x11mon:0,xallexcept:0,xapi:0,xapian:0,xapian_flush_threshold:0,xapiandb:0,xattr:0,xattrtofield:0,xdg:0,xdm:0,xdocid:0,xesam:0,xlsx:0,xml:0,xmtag:0,xpdf:0,xsession:0,xsl:0,xslt:0,xsltproc:0,xul:0,xxx:0,xymfld:0,year:0,yet:0,yield:0,ymmv:0,young:0,your:0,yyyy:0,zeitgeist:0,zero:0,zip:0,zipfil:0,zipskippednam:0,zipuseskippednam:0,zlib:0,zone:0},titles:["Recoll user manual"],titleterms:{"case":0,"default":0,"import":0,"new":0,"try":0,about:0,access:0,adding:0,adjust:0,advanc:0,affect:0,anchore:0,api:0,applet:0,arbitrari:0,aspect:0,attach:0,attribut:0,autom:0,automat:0,avanc:0,big:0,binari:0,build:0,claus:0,click:0,collaps:0,command:0,compat:0,complex:0,conf:0,configur:0,consider:0,contain:0,content:0,copi:0,creat:0,cron:0,custom:0,daemon:0,data:0,desktop:0,detail:0,diacrit:0,displai:0,document:0,duplic:0,element:0,environ:0,exampl:0,expans:0,explor:0,extend:0,extern:0,external:0,extract:0,failur:0,field:0,file:0,filter:0,find:0,format:0,fragment:0,from:0,full:0,gener:0,give:0,graphic:0,gui:0,handler:0,histori:0,hotkei:0,how:0,impact:0,index:0,indice:[],input:0,insid:0,install:0,installat:0,integr:0,interfac:0,introduct:0,kde:0,kicker:0,kio:0,languag:0,later:0,line:0,list:0,locat:0,main:0,manual:0,menu:0,mimeconf:0,mimemap:0,mimeview:0,miscellan:0,mode:0,modifi:0,modul:0,more:0,multipl:0,non:0,number:0,ocr:0,organ:0,other:0,output:0,overview:0,packag:0,page:0,paragraph:0,paramet:0,path:0,pdf:0,perform:0,period:0,phrase:0,prerequisit:0,preview:0,previou:0,process:0,program:0,proxim:0,ptran:0,python:0,queri:0,rang:0,rcl:0,rclextract:0,real:0,recol:0,recoveri:0,remov:0,resourc:0,restor:0,result:0,right:0,run:0,sampl:0,save:0,script:0,search:0,searchabl:0,secur:0,self:0,sensit:0,set:0,shortcut:0,simpl:0,slave:0,solari:0,sort:0,sourc:0,special:0,specif:0,spell:0,start:0,storag:0,store:0,suggest:0,support:0,synonym:0,tab:0,tabl:0,tag:0,tell:0,term:0,tesseract:0,text:0,thi:0,thing:0,thread:0,thumbnail:0,time:0,tip:0,tool:0,translat:0,type:0,updat:0,usag:0,user:0,using:0,variabl:0,version:0,viewer:0,volum:0,web:0,welcom:[],what:0,where:0,which:0,wildcard:0,window:0,wisit:0,work:0,write:0,xap:0,xmp:0,you:0}}) \ No newline at end of file diff --git a/src/doc/user/sphinx/_build/html/source/usermanual.html b/src/doc/user/sphinx/_build/html/source/usermanual.html deleted file mode 100644 index 531ae96c..00000000 --- a/src/doc/user/sphinx/_build/html/source/usermanual.html +++ /dev/null @@ -1,5435 +0,0 @@ - - - - - - - - Recoll user manual — recoll 1.25.12 documentation - - - - - - - - - - - - - - - - - - - - -
-
-
-
- -
-

Recoll user manual

- --- - - - -
Author:Jean-Francois Dockes
- -
-

Introduction

-

This document introduces full text search notions and describes the -installation and use of the RCL application. It is updated for RCL -RCLVERSION.

-

RCL was for a long time dedicated to Unix-like systems. It was only -lately (2015) ported to MS-Windows. Many references in this manual, -especially file locations, are specific to Unix, and not valid on WIN, -where some described features are also not available. The manual will be -progressively updated. Until this happens, on WIN, most references to -shared files can be translated by looking under the Recoll installation -directory (esp. the Share subdirectory). The user configuration is -stored by default under AppData/Local/Recoll inside the user -directory, along with the index itself.

-
-

Giving it a try

-

If you do not like reading manuals (who does?) but wish to give RCL a -try, just install the application and start -the recoll graphical user interface (GUI), which will ask permission -to index your home directory by default, allowing you to search -immediately after indexing completes.

-

Do not do this if your home directory contains a huge number of -documents and you do not want to wait or are very short on disk space. -In this case, you may first want to customize the -configuration to restrict the indexed area -(for the very impatient with a completed package install, from the -recoll GUI: Preferences > Indexing configuration, then adjust the -Top directories section).

-

On Unix/Linux, you may need to install the appropriate supporting -applications for document types that need -them (for example antiword for Microsoft Word files).

-

The RCL for WIN package is self-contained and includes most useful -auxiliary programs. You will just need to install Python 2.7.

-
- -
-

Recoll overview

-

RCL uses the XAP information retrieval -library as its storage and retrieval engine. XAP is a very mature -package using a sophisticated probabilistic ranking -model.

-

The XAP library manages an index database which describes where terms -appear in your document files. It efficiently processes the complex -queries which are produced by the RCL query expansion mechanism, and is -in charge of the all-important relevance computation task.

-

RCL provides the mechanisms and interface to get data into and out of -the index. This includes translating the many possible document formats -into pure text, handling term variations (using XAP stemmers), and -spelling approximations (using the aspell speller), interpreting user -queries and presenting results.

-

In a shorter way, RCL does the dirty footwork, XAP deals with the -intelligent parts of the process.

-

The XAP index can be big (roughly the size of the original document -set), but it is not a document archive. RCL can only display documents -that still exist at the place from which they were indexed. (Actually, -there is a way to reconstruct a document from the information in the -index, but only the pure text is saved, possibly without punctuation and -capitalization, depending on RCL version).

-

RCL stores all internal data in Unicode UTF-8 format, and it can index -files of many types with different character sets, encodings, and -languages into the same index. It can process documents embedded inside -other documents (for example a pdf document stored inside a Zip archive -sent as an email attachment...), down to an arbitrary depth.

-

Stemming is the process by which RCL reduces words to their radicals so -that searching does not depend, for example, on a word being singular or -plural (floor, floors), or on a verb tense (flooring, floored). Because -the mechanisms used for stemming depend on the specific grammatical -rules for each language, there is a separate XAP stemmer module for most -common languages where stemming makes sense.

-

RCL stores the unstemmed versions of terms in the main index and uses -auxiliary databases for term expansion (one for each stemming language), -which means that you can switch stemming languages between searches, or -add a language without needing a full reindex.

-

Storing documents written in different languages in the same index is -possible, and commonly done. In this situation, you can specify several -stemming languages for the index.

-

RCL currently makes no attempt at automatic language recognition, which -means that the stemmer will sometimes be applied to terms from other -languages with potentially strange results. In practise, even if this -introduces possibilities of confusion, this approach has been proven -quite useful, and it is much less cumbersome than separating your -documents according to what language they are written in.

-

By default, RCL strips most accents and diacritics from terms, and -converts them to lower case before either storing them in the index or -searching for them. As a consequence, it is impossible to search for a -particular capitalization of a term (US / us), or to -discriminate two terms based on diacritics (sake / saké, -mate / maté).

-

RCL can optionally store the raw terms, without accent stripping or case -conversion. In this configuration, default searches will behave as -before, but it is possible to perform searches sensitive to case and -diacritics. This is described in more detail in the section about index -case and diacritics sensitivity.

-

RCL has many parameters which define exactly what to index, and how to -classify and decode the source documents. These are kept in -configuration files. A default configuration -is copied into a standard location (usually something like -/usr/share/recoll/examples) during installation. The default values -set by the configuration files in this directory may be overridden by -values set inside your personal configuration, found by default in the -.recoll sub-directory of your home directory. The default -configuration will index your home directory with default parameters and -should be sufficient for giving RCL a try, but you may want to adjust it -later, which can be done either by editing the text files or by using -configuration menus in the recoll GUI. Some other parameters -affecting only the recoll GUI are stored in the standard location -defined by Qt.

-

The indexing process is started -automatically (after asking permission), the first time you execute the -recoll GUI. Indexing can also be performed by executing the -recollindex command. RCL indexing is multithreaded by default when -appropriate hardware resources are available, and can perform in -parallel multiple tasks for text extraction, segmentation and index -updates.

-

Searches are usually performed inside the recoll -GUI, which has many options to help you find what you are looking for. -However, there are other ways to perform RCL searches:

- -
-
-
-

Indexing

-
-

Introduction

-

Indexing is the process by which the set of documents is analyzed and -the data entered into the database. RCL indexing is normally -incremental: documents will only be processed if they have been modified -since the last run. On the first execution, all documents will need -processing. A full index build can be forced later by specifying an -option to the indexing command (recollindex -z or -Z).

-

recollindex skips files which caused an error during a previous -pass. This is a performance optimization, and a new behaviour in version -1.21 (failed files were always retried by previous versions). The -command line option -k can be set to retry failed files, for example -after updating an input handler.

-

The following sections give an overview of different aspects of the -indexing processes and configuration, with links to detailed sections.

-

Depending on your data, temporary files may be needed during indexing, -some of them possibly quite big. You can use the RECOLL_TMPDIR or -TMPDIR environment variables to determine where they are created (the -default is to use /tmp). Using TMPDIR has the nice property that it -may also be taken into account by auxiliary commands executed by -recollindex.

-
-

Indexing modes

-

RCL indexing can be performed along two main modes:

-
    -
  • `Periodic (or batch) indexing: <#RCL.INDEXING.PERIODIC>`__.

    -

    recollindex is executed at discrete times. The typical usage is -to have a nightly run programmed -into your cron file.

    -
  • -
  • `Real time indexing: <#RCL.INDEXING.MONITOR>`__.

    -

    recollindex runs permanently as a daemon and uses a file system -alteration monitor (e.g. inotify) to detect file changes. New or -updated files are indexed at once.

    -
  • -
-

The choice between the two methods is mostly a matter of preference, and -they can be combined by setting up multiple indexes (ie: use periodic -indexing on a big documentation directory, and real time indexing on a -small home directory). Monitoring a big file system tree can consume -significant system resources.

-

With RCL 1.24 and newer, it is also possible to set up an index so that -only a subset of the tree will be monitored and the rest will be covered -by batch/incremental indexing. (See the details in the Real time -indexing section.

-

The choice of method and the parameters used can be configured from the -recoll GUI: Preferences > Indexing schedule

-

The GUI File menu also has entries to start or stop the current indexing -operation. Stopping indexing is performed by killing the recollindex -process, which will checkpoint its state and exit. A later restart of -indexing will mostly resume from where things stopped (the file tree -walk has to be restarted from the beginning).

-

When the real time indexer is running, two operations are available from -the menu: ‘Stop’ and ‘Trigger incremental pass’. When no indexing is -running, you have a choice of updating the index or rebuilding it (the -first choice only processes changed files, the second one zeroes the -index before starting so that all files are processed).

-
-
-

Configurations, multiple indexes

-

RCL supports defining multiple indexes, each defined by its own -configuration directory, in which several -configuration files describe what should be indexed and how.

-

A default personal configuration directory ($HOME/.recoll/) is -created when a RCL program is first executed. This configuration is the -one used for indexing and querying when no specific configuration is -specified.

-

All configuration parameters have defaults, defined in system-wide -files. Without further customisation, the default configuration will -process your complete home directory, with a reasonable set of defaults. -It can be changed to process a different area of the file system, select -files in different ways, and many other things.

-

In some cases, it may be useful to create additional configuration -directories, for example, to separate personal and shared indexes, or to -take advantage of the organization of your data to improve search -precision.

-

A plausible usage scenario for the multiple index feature would be for a -system administrator to set up a central index for shared data, that you -choose to search or not in addition to your personal data. Of course, -there are other possibilities. for example, there are many cases where -you know the subset of files that should be searched, and where -narrowing the search can improve the results. You can achieve -approximately the same effect with the directory filter in advanced -search, but multiple indexes may have better performance and may be -worth the trouble in some cases.

-

A more advanced use case would be to use multiple index to improve -indexing performance, by updating several indexes in parallel (using -multiple CPU cores and disks, or possibly several machines), and then -merging them, or querying them in parallel.

-

A specific configuration can be selected by setting the RECOLL_CONFDIR -environment variable, or giving the -c option to any of the RCL -commands.

-

When creating or updating indexes, the different configurations are -entirely independant (no parameters are ever shared between -configurations when indexing). The recollindex program always works -on a single index.

-

When querying, multiple indexes can be accessed concurrently, either -from the GUI or the command line. When doing this, there is always one -main configuration, from which both configuration and index data are -used. Only the index data from the additional indexes is used (their -configuration parameters are ignored).

-

The behaviour of index update and query regarding multiple -configurations is important and sometimes confusing, so it will be -rephrased here: for index generation, multiple configurations are -totally independant from each other. When querying, configuration and -data are used from the main index (the one designated by -c or -RECOLL_CONFDIR), and only the data from the additional indexes is used. -This implies that some parameters should be consistent among the -configurations for indexes which are to be used together.

-

See the section about configuring multiple -indexes for more detail

-
-
-

Document types

-

RCL knows about quite a few different document types. The parameters for -document types recognition and processing are set in configuration -files.

-

Most file types, like HTML or word processing files, only hold one -document. Some file types, like email folders or zip archives, can hold -many individually indexed documents, which may themselves be compound -ones. Such hierarchies can go quite deep, and RCL can process, for -example, a LibreOffice document stored as an attachment to an email -message inside an email folder archived in a zip file...

-

recollindex processes plain text, HTML, OpenDocument -(Open/LibreOffice), email formats, and a few others internally.

-

Other file types (ie: postscript, pdf, ms-word, rtf ...) need external -applications for preprocessing. The list is in the -installation section. After every indexing -operation, RCL updates a list of commands that would be needed for -indexing existing files types. This list can be displayed by selecting -the menu option File > Show Missing Helpers in the recoll GUI. It is -stored in the missing text file inside the configuration directory.

-

By default, RCL will try to index any file type that it has a way to -read. This is sometimes not desirable, and there are ways to either -exclude some types, or on the contrary define a positive list of types -to be indexed. In the latter case, any type not in the list will be -ignored.

-

Excluding files by name can be done by adding wildcard name patterns to -the skippedNames list, -which can be done from the GUI Index configuration menu. Excluding by -type can be done by setting the -excludedmimetypes -list in the configuration file (1.20 and later). This can be redefined -for subdirectories.

-

You can also define an exclusive list of MIME types to be indexed (no -others will be indexed), by settting the -indexedmimetypes -configuration variable. Example:

-
indexedmimetypes = text/html application/pdf
-
-
-

It is possible to redefine this parameter for subdirectories. Example:

-
[/path/to/my/dir]
-indexedmimetypes = application/pdf
-
-
-

(When using sections like this, don’t forget that they remain in effect -until the end of the file or another section indicator).

-

excludedmimetypes or indexedmimetypes, can be set either by -editing the configuration file -(``recoll.conf`) <#RCL.INSTALL.CONFIG.RECOLLCONF>`__ for the index, or -by using the GUI index configuration tool.

-
-

Note

-

When editing the indexedmimetypes or excludedmimetypes -lists, you should use the MIME values listed in the mimemap file -or in Recoll result lists in preference to file -i output: there -are a number of differences. The file -i output should only be -used for files without extensions, or for which the extension is not -listed in mimemap

-
-
-
-

Indexing failures

-

Indexing may fail for some documents, for a number of reasons: a helper -program may be missing, the document may be corrupt, we may fail to -uncompress a file because no file system space is available, etc.

-

RCL versions prior to 1.21 always retried to index files which had -previously caused an error. This guaranteed that anything that may have -become indexable (for example because a helper had been installed) would -be indexed. However this was bad for performance because some indexing -failures may be quite costly (for example failing to uncompress a big -file because of insufficient disk space).

-

The indexer in RCL versions 1.21 and later does not retry failed files -by default. Retrying will only occur if an explicit option (-k) is -set on the recollindex command line, or if a script executed when -recollindex starts up says so. The script is defined by a -configuration variable (checkneedretryindexscript), and makes a -rather lame attempt at deciding if a helper command may have been -installed, by checking if any of the common bin directories have -changed.

-
-
-

Recovery

-

In the rare case where the index becomes corrupted (which can signal -itself by weird search results or crashes), the index files need to be -erased before restarting a clean indexing pass. Just delete the -xapiandb directory (see next section), -or, alternatively, start the next recollindex with the -z -option, which will reset the database before indexing. The difference -between the two methods is that the second will not change the current -index format, which may be undesirable if a newer format is supported by -the XAP version.

-
-
-
-

Index storage

-

The default location for the index data is the xapiandb subdirectory -of the RCL configuration directory, typically -$HOME/.recoll/xapiandb/. This can be changed via two different -methods (with different purposes):

-
    -
  1. For a given configuration directory, you can specify a non-default -storage location for the index by setting the dbdir parameter in -the configuration file (see the configuration -section). This method would -mainly be of use if you wanted to keep the configuration directory in -its default location, but desired another location for the index, -typically out of disk occupation or performance concerns.

    -
  2. -
  3. You can specify a different configuration directory by setting the -RECOLL_CONFDIR environment variable, or using the -c option to -the RCL commands. This method would typically be used to index -different areas of the file system to different indexes. For example, -if you were to issue the following command:

    -
    recoll -c ~/.indexes-email
    -
    -
    -

    Then RCL would use configuration files stored in -~/.indexes-email/ and, (unless specified otherwise in -recoll.conf) would look for the index in -~/.indexes-email/xapiandb/.

    -

    Using multiple configuration directories and configuration -options allows you to tailor -multiple configurations and indexes to handle whatever subset of the -available data you wish to make searchable.

    -
  4. -
-

The size of the index is determined by the size of the set of documents, -but the ratio can vary a lot. For a typical mixed set of documents, the -index size will often be close to the data set size. In specific cases -(a set of compressed mbox files for example), the index can become much -bigger than the documents. It may also be much smaller if the documents -contain a lot of images or other non-indexed data (an extreme example -being a set of mp3 files where only the tags would be indexed).

-

Of course, images, sound and video do not increase the index size, which -means that in most cases, the space used by the index will be negligible -against the total amount of data on the computer.

-

The index data directory (xapiandb) only contains data that can be -completely rebuilt by an index run (as long as the original documents -exist), and it can always be destroyed safely.

-
-

XAP index formats

-

XAP versions usually support several formats for index storage. A given -major XAP version will have a current format, used to create new -indexes, and will also support the format from the previous major -version.

-

XAP will not convert automatically an existing index from the older -format to the newer one. If you want to upgrade to the new format, or if -a very old index needs to be converted because its format is not -supported any more, you will have to explicitly delete the old index -(typically ~/.recoll/xapiandb), then run a normal indexing command. -Using recollindex option -z would not work in this situation.

-
-
-

Security aspects

-

The RCL index does not hold complete copies of the indexed documents (it -almost does after version 1.24). But it does hold enough data to allow -for an almost complete reconstruction. If confidential data is indexed, -access to the database directory should be restricted.

-

RCL will create the configuration directory with a mode of 0700 (access -by owner only). As the index data directory is by default a -sub-directory of the configuration directory, this should result in -appropriate protection.

-

If you use another setup, you should think of the kind of protection you -need for your index, set the directory and files access modes -appropriately, and also maybe adjust the umask used during index -updates.

-
-
-

Special considerations for big indexes

-

This only needs concern you if your index is going to be bigger than -around 5 GBytes. Beyond 10 GBytes, it becomes a serious issue. Most -people have much smaller indexes. For reference, 5 GBytes would be -around 2000 bibles, a lot of text. If you have a huge text dataset -(remember: images don’t count, the text content of PDFs is typically -less than 5% of the file size), read on.

-

The amount of writing performed by Xapian during index creation is not -linear with the index size (it is somewhere between linear and -quadratic). For big indexes this becomes a performance issue, and may -even be an SSD disk wear issue.

-

The problem can be mitigated by observing the following rules:

-
    -
  • Partition the data set and create several indexes of reasonable size -rather than a huge one. These indexes can then be queried in parallel -(using the RCL external indexes facility), or merged using -xapian-compact.
  • -
  • Have a lot of RAM available and set the idxflushmb RCL -configuration parameter as high as you can without swapping -(experimentation will be needed). 200 would be a minimum in this -context.
  • -
  • Use Xapian 1.4.10 or newer, as this version brought a significant -improvement in the amount of writes.
  • -
-
-
-
-

Index configuration

-

Variables set inside the RCL configuration -files control which areas of the file system -are indexed, and how files are processed. These variables can be set -either by editing the text files or by using the dialogs in the -``recoll` GUI <#RCL.INDEXING.CONFIG.GUI>`__.

-

The first time you start recoll, you will be asked whether or not -you would like it to build the index. If you want to adjust the -configuration before indexing, just click Cancel at this point, which -will get you into the configuration interface. If you exit at this -point, recoll will have created a ~/.recoll directory containing -empty configuration files, which you can edit by hand.

-

The configuration is documented inside the installation -chapter of this document, or in the recoll.conf -5 man page, but the most current information will most likely be the -comments inside the sample file. The most immediately useful variable is -probably `topdirs <#RCL.INSTALL.CONFIG.RECOLLCONF.TOPDIRS>`__, which -determines what subtrees and files get indexed.

-

The applications needed to index file types other than text, HTML or -email (ie: pdf, postscript, ms-word...) are described in the external -packages section.

-

As of Recoll 1.18 there are two incompatible types of Recoll indexes, -depending on the treatment of character case and diacritics. A further -section describes the two types in more -detail.

-
-

Multiple indexes

-

Multiple RCL indexes can be created by using several configuration -directories which are typically set to index different areas of the file -system. A specific index can be selected for updating or searching, -using the RECOLL_CONFDIR environment variable or the -c option to -recoll and recollindex.

-

Index configuration parameters can be set either by using a text editor -on the files, or, for most parameters, by using the recoll index -configuration GUI. In the latter case, the configuration directory for -which parameters are modified is the one which was selected by -RECOLL_CONFDIR or the -c parameter, and there is no way to switch -configurations within the GUI.

-

As a remainder from a previous section, a recollindex program -instance can only update one specific index, and it will only use -parameters from a single configuration (no parameters are ever shared -between configurations when indexing). All the query methods -(recoll, recollq, the Python API, etc.) operate with a main -configuration, from which both configuration and index data are used, -but can also query data from multiple additional indexes. Only the index -data from the latter is used, their configuration parameters are -ignored.

-

When searching, the current main index (defined by RECOLL_CONFDIR or --c) is always active. If this is undesirable, you can set up your -base configuration to index an empty directory.

-

If a set of multiple indexes are to be used together for searches, some -configuration parameters must be consistent among the set. These are -parameters which need to be the same when indexing and searching. As the -parameters come from the main configuration when searching, they need to -be compatible with what was set when creating the other indexes (which -came from their respective configuration directories).

-

Most importantly, all indexes to be queried concurrently must have the -same option concerning character case and diacritics stripping, but -there are other constraints. Most of the relevant parameters are -described in the linked -section.

-

The different search interfaces (GUI, command line, ...) have different -methods to define the set of indexes to be used, see the appropriate -section.

-

At the moment, using multiple configurations implies a small level of -command line usage. Additional configuration directories (beyond -~/.recoll) must be created by hand (mkdir or such), the GUI will -not do it. This is to avoid mistakenly creating additional directories -when an argument is mistyped. Also, the GUI or the indexer must be -launched with a specific option or environment to work on the right -configuration.

-

To be more practical, here follows a few examples of the commands need -to create, configure, update, and query an additional index.

-

Initially creating the configuration and index:

-
mkdir /path/to/my/new/config
-
-
-

Configuring the new index can be done from the recoll GUI, launched -from the command line to pass the -c option (you could create a -desktop file to do it for you), and then using the GUI index -configuration tool to set up the index.

-
recoll -c /path/to/my/new/config
-
-
-

Alternatively, you can just start a text editor on the main -configuration file ```recoll.conf

-
-
`` <#RCL.INSTALL.CONFIG.RECOLLCONF>`__.
-

Creating and updating the index can be done from the command line:

-
recollindex -c /path/to/my/new/config
-
-
-

or from the File menu of a GUI launched with the same option -(recoll, see above).

-

The same GUI would also let you set up batch indexing for the new index. -Real time indexing can only be set up from the GUI for the default index -(the menu entry will be inactive if the GUI was started with a -non-default -c option).

-

The new index can be queried alone with

-
recoll -c /path/to/my/new/config
-
-
-

Or, in parallel with the default index, by starting recoll without a --c option, and using the Preferences > External Index Dialog menu.

-
-
-

Index case and diacritics sensitivity

-

As of RCL version 1.18 you have a choice of building an index with terms -stripped of character case and diacritics, or one with raw terms. For a -source term of Résumé, the former will store resume, the latter -Résumé.

-

Each type of index allows performing searches insensitive to case and -diacritics: with a raw index, the user entry will be expanded to match -all case and diacritics variations present in the index. With a stripped -index, the search term will be stripped before searching.

-

A raw index allows for another possibility which a stripped index cannot -offer: using case and diacritics to discriminate between terms, -returning different results when searching for US and us or -resume and résumé. Read the section about search case and -diacritics sensitivity for more details.

-

The type of index to be created is controlled by the indexStripChars -configuration variable which can only be changed by editing the -configuration file. Any change implies an index reset (not automated by -RCL), and all indexes in a search must be set in the same way (again, -not checked by RCL).

-

If the indexStripChars is not set, RCL 1.18 creates a stripped index -by default, for compatibility with previous versions.

-

As a cost for added capability, a raw index will be slightly bigger than -a stripped one (around 10%). Also, searches will be more complex, so -probably slightly slower, and the feature is still young, so that a -certain amount of weirdness cannot be excluded.

-

One of the most adverse consequence of using a raw index is that some -phrase and proximity searches may become impossible: because each term -needs to be expanded, and all combinations searched for, the -multiplicative expansion may become unmanageable.

-
-
-

Indexing threads configuration

-

The RCL indexing process recollindex can use multiple threads to -speed up indexing on multiprocessor systems. The work done to index -files is divided in several stages and some of the stages can be -executed by multiple threads. The stages are:

-
    -
  1. File system walking: this is always performed by the main thread.
  2. -
  3. File conversion and data extraction.
  4. -
  5. Text processing (splitting, stemming, etc.).
  6. -
  7. XAP index update.
  8. -
-

You can also read a longer -document -about the transformation of RCL indexing to multithreading.

-

The threads configuration is controlled by two configuration file -parameters.

-
-
thrQSizes
-
This variable defines the job input queues configuration. There are -three possible queues for stages 2, 3 and 4, and this parameter -should give the queue depth for each stage (three integer values). -If a value of -1 is used for a given stage, no queue is used, and -the thread will go on performing the next stage. In practise, deep -queues have not been shown to increase performance. A value of 0 for -the first queue tells RCL to perform autoconfiguration (no need for -anything else in this case, thrTCounts is not used) - this is the -default configuration.
-
thrTCounts
-

This defines the number of threads used for each stage. If a value -of -1 is used for one of the queue depths, the corresponding thread -count is ignored. It makes no sense to use a value other than 1 for -the last stage because updating the XAP index is necessarily -single-threaded (and protected by a mutex).

-

Note

-

If the first value in thrQSizes is 0, thrTCounts is ignored.

-
-
-

The following example would use three queues (of depth 2), and 4 threads -for converting source documents, 2 for processing their text, and one to -update the index. This was tested to be the best configuration on the -test system (quadri-processor with multiple disks).

-
thrQSizes = 2 2 2
-thrTCounts =  4 2 1
-
-
-

The following example would use a single queue, and the complete -processing for each document would be performed by a single thread -(several documents will still be processed in parallel in most cases). -The threads will use mutual exclusion when entering the index update -stage. In practise the performance would be close to the precedent case -in general, but worse in certain cases (e.g. a Zip archive would be -performed purely sequentially), so the previous approach is preferred. -YMMV... The 2 last values for thrTCounts are ignored.

-
thrQSizes = 2 -1 -1
-thrTCounts =  6 1 1
-
-
-

The following example would disable multithreading. Indexing will be -performed by a single thread.

-
thrQSizes = -1 -1 -1
-
-
-
-
-

The index configuration GUI

-

Most parameters for a given index configuration can be set from a -recoll GUI running on this configuration (either as default, or by -setting RECOLL_CONFDIR or the -c option.)

-

The interface is started from the Preferences > Index Configuration menu -entry. It is divided in four tabs, Global parameters, Local parameters, -Web history (which is explained in the next section) and Search -parameters.

-

The Global parameters tab allows setting global variables, like the -lists of top directories, skipped paths, or stemming languages.

-

The Local parameters tab allows setting variables that can be redefined -for subdirectories. This second tab has an initially empty list of -customisation directories, to which you can add. The variables are then -set for the currently selected directory (or at the top level if the -empty line is selected).

-

The Search parameters section defines parameters which are used at query -time, but are global to an index and affect all search tools, not only -the GUI.

-

The meaning for most entries in the interface is self-evident and -documented by a ToolTip popup on the text label. For more detail, -you will need to refer to the configuration -section of this guide.

-

The configuration tool normally respects the comments and most of the -formatting inside the configuration file, so that it is quite possible -to use it on hand-edited files, which you might nevertheless want to -backup first...

-
-
-
-

Indexing the WEB pages which you wisit.

-

With the help of a Firefox extension, RCL can index the Internet pages -that you visit. The extension has a long history: it was initially -designed for the Beagle indexer, then adapted to RCL and the Firefox XUL -API. A new version of the addon has been written to work with the -WebExtensions API, which is the only one supported after Firefox version -57.

-

The extension works by copying visited WEB pages to an indexing queue -directory, which RCL then processes, indexing the data, storing it into -a local cache, then removing the file from the queue.

-

Because the WebExtensions API introduces more constraints to what -extensions can do, the new version works with one more step: the files -are first created in the browser default downloads location (typically -$HOME/Downloads ), then moved by a script in the old queue location. -The script is automatically executed by the RCL indexer versions 1.23.5 -and newer. It could conceivably be executed independantly to make the -new browser extension compatible with an older RCL version (the script -is named recoll-we-move-files.py).

-
-

Note

-

For the WebExtensions-based version to work, it is necessary to set -the webdownloadsdir value in the configuration if it was changed -from the default $HOME/Downloads in the browser preferences.

-
-

The visited WEB pages indexing feature can be enabled on the RCL side -from the GUI Index configuration panel, or by editing the configuration -file (set processwebqueue to 1).

-

A current pointer to the extension can be found, along with up-to-date -instructions, on the Recoll wiki.

-

A copy of the indexed WEB pages is retained by Recoll in a local cache -(from which previews can be fetched). The cache size can be adjusted -from the Index configuration / Web history panel. Once the maximum size -is reached, old pages are purged - both from the cache and the index - -to make room for new ones, so you need to explicitly archive in some -other place the pages that you want to keep indefinitely.

-
-
-

Extended attributes data

-

User extended attributes are named pieces of information that most -modern file systems can attach to any file.

-

RCL versions 1.19 and later process extended attributes as document -fields by default. For older versions, this has to be activated at build -time.

-

A freedesktop -standard -defines a few special attributes, which are handled as such by RCL:

-
-
mime_type
-
If set, this overrides any other determination of the file MIME -type.
-
charset
-
If set, this defines the file character set (mostly useful for plain -text files).
-
-

By default, other attributes are handled as RCL fields. On Linux, the -user prefix is removed from the name. This can be configured more -precisely inside the `fields configuration -file <#RCL.INSTALL.CONFIG.FIELDS>`__.

-
-
-

Importing external tags

-

During indexing, it is possible to import metadata for each file by -executing commands. For example, this could extract user tag data for -the file and store it in a field for indexing.

-

See the section about the ``metadatacmds` -field <#RCL.INSTALL.CONFIG.RECOLLCONF.METADATACMDS>`__ in the main -configuration chapter for a description of the configuration syntax.

-

As an example, if you would want RCL to use tags managed by tmsu, you -would add the following to the configuration file:

-
[/some/area/of/the/fs]
-      metadatacmds = ; tags = tmsu tags %f
-
-
-**Note**
-
-Depending on the tmsu version, you may need/want to add options like
-``--database=/some/db``.
-
-
-

You may want to restrict this processing to a subset of the directory -tree, because it may slow down indexing a bit -([some/area/of/the/fs]).

-

Note the initial semi-colon after the equal sign.

-

In the example above, the output of tmsu is used to set a field -named tags. The field name is arbitrary and could be tmsu or -myfield just the same, but tags is an alias for the standard RCL -keywords field, and the tmsu output will just augment its -contents. This will avoid the need to extend the field -configuration.

-

Once re-indexing is performed (you’ll need to force the file reindexing, -RCL will not detect the need by itself), you will be able to search from -the query language, through any of its aliases: -tags:some/alternate/values or tags:all,these,values (the compact -field search syntax is supported for recoll 1.20 and later. For older -versions, you would need to repeat the tags: specifier for each -term, e.g. ``tags:some OR

-
-
tags:alternate``).
-

You should be aware that tags changes will not be detected by the -indexer if the file itself did not change. One possible workaround would -be to update the file ctime when you modify the tags, which would be -consistent with how extended attributes function. A pair of chmod -commands could accomplish this, or a touch -a . Alternatively, just -couple the tag update with a ``recollindex -e -i

-
-
filename.``
-
-
-

The PDF input handler

-

The PDF format is very important for scientific and technical -documentation, and document archival. It has extensive facilities for -storing metadata along with the document, and these facilities are -actually used in the real world.

-

In consequence, the rclpdf.py PDF input handler has more complex -capabilities than most others, and it is also more configurable. -Specifically, rclpdf.py can automatically use tesseract to perform -OCR if the document text is empty, it can be configured to extract -specific metadata tags from an XMP packet, and to extract PDF -attachments.

-
-

OCR with Tesseract

-

If both tesseract and pdftoppm (generally from the poppler-utils -package) are installed, the PDF handler may attempt OCR on PDF files -with no text content. This is controlled by the -pdfocr configuration -variable, which is false by default because OCR is very slow.

-

The choice of language is very important for successfull OCR. Recoll has -currently no way to determine this from the document itself. You can set -the language to use through the contents of a .ocrpdflang text file -in the same directory as the PDF document, or through the -RECOLL_TESSERACT_LANG environment variable, or through the contents of -an ocrpdf text file inside the configuration directory. If none of -the above are used, RCL will try to guess the language from the NLS -environment.

-
-
-

XMP fields extraction

-

The rclpdf.py script in RCL version 1.23.2 and later can extract XMP -metadata fields by executing the pdfinfo command (usually found with -poppler-utils). This is controlled by the -pdfextrameta -configuration variable, which specifies which tags to extract and, -possibly, how to rename them.

-

The pdfextrametafix -variable can be used to designate a file with Python code to edit the -metadata fields (available for RCL 1.23.3 and later. 1.23.2 has -equivalent code inside the handler script). Example:

-
import sys
-        import re
-
-        class MetaFixer(object):
-        def __init__(self):
-        pass
-
-        def metafix(self, nm, txt):
-        if nm == 'bibtex:pages':
-        txt = re.sub(r'--', '-', txt)
-        elif nm == 'someothername':
-        # do something else
-        pass
-        elif nm == 'stillanother':
-        # etc.
-        pass
-
-        return txt
-        def wrapup(self, metaheaders):
-        pass
-
-
-

If the ‘metafix()’ method is defined, it is called for each metadata -field. A new MetaFixer object is created for each PDF document (so the -object can keep state for, for example, eliminating duplicate values). -If the ‘wrapup()’ method is defined, it is called at the end of XMP -fields processing with the whole metadata as parameter, as an array of -‘(nm, val)’ pairs, allowing an alternate approach for editing or -adding/deleting fields.

-
-
-

PDF attachment indexing

-

If pdftk is installed, and if the the -pdfattach configuration -variable is set, the PDF input handler will try to extract PDF -attachements for indexing as sub-documents of the PDF file. This is -disabled by default, because it slows down PDF indexing a bit even if -not one attachment is ever found (PDF attachments are uncommon in my -experience).

-
-
-
-

Periodic indexing

-
-

Running indexing

-

Indexing is always performed by the recollindex program, which can -be started either from the command line or from the File menu in the -recoll GUI program. When started from the GUI, the indexing will run -on the same configuration recoll was started on. When started from -the command line, recollindex will use the RECOLL_CONFDIR variable -or accept a -c confdir option to specify a non-default configuration -directory.

-

If the recoll program finds no index when it starts, it will -automatically start indexing (except if canceled).

-

The recollindex indexing process can be interrupted by sending an -interrupt (Ctrl-C, SIGINT) or terminate (SIGTERM) signal. Some time may -elapse before the process exits, because it needs to properly flush and -close the index. This can also be done from the recoll GUI File > -Stop Indexing menu entry.

-

After such an interruption, the index will be somewhat inconsistent -because some operations which are normally performed at the end of the -indexing pass will have been skipped (for example, the stemming and -spelling databases will be inexistant or out of date). You just need to -restart indexing at a later time to restore consistency. The indexing -will restart at the interruption point (the full file tree will be -traversed, but files that were indexed up to the interruption and for -which the index is still up to date will not need to be reindexed).

-

recollindex has a number of other options which are described in its -man page. Only a few will be described here.

-

Option -z will reset the index when starting. This is almost the -same as destroying the index files (the nuance is that the XAP format -version will not be changed).

-

Option -Z will force the update of all documents without resetting -the index first. This will not have the “clean start” aspect of -z, -but the advantage is that the index will remain available for querying -while it is rebuilt, which can be a significant advantage if it is very -big (some installations need days for a full index rebuild).

-

Option -k will force retrying files which previously failed to be -indexed, for example because of a missing helper program.

-

Of special interest also, maybe, are the -i and -f options. --i allows indexing an explicit list of files (given as command line -parameters or read on stdin). -f tells recollindex to ignore -file selection parameters from the configuration. Together, these -options allow building a custom file selection process for some area of -the file system, by adding the top directory to the skippedPaths -list and using an appropriate file selection method to build the file -list to be fed to recollindex -if. Trivial example:

-
find . -name indexable.txt -print | recollindex -if
-
-
-

recollindex -i will not descend into subdirectories specified as -parameters, but just add them as index entries. It is up to the external -file selection method to build the complete file list.

-
-
-

Using cron to automate indexing

-

The most common way to set up indexing is to have a cron task execute it -every night. For example the following crontab entry would do it -every day at 3:30AM (supposing recollindex is in your PATH):

-
30 3 * * * recollindex > /some/tmp/dir/recolltrace 2>&1
-
-
-

Or, using anacron:

-
1  15  su mylogin -c "recollindex recollindex > /tmp/rcltraceme 2>&1"
-
-
-

As of version 1.17 the RCL GUI has dialogs to manage crontab entries -for recollindex. You can reach them from the Preferences > Indexing -Schedule menu. They only work with the good old cron, and do not -give access to all features of cron scheduling.

-

The usual command to edit your crontab is crontab -e (which -will usually start the vi editor to edit the file). You may have -more sophisticated tools available on your system.

-

Please be aware that there may be differences between your usual -interactive command line environment and the one seen by crontab -commands. Especially the PATH variable may be of concern. Please check -the crontab manual pages about possible issues.

-
-
-
-

Real time indexing

-

Real time monitoring/indexing is performed by starting the -recollindex -m command. With this option, recollindex will -detach from the terminal and become a daemon, permanently monitoring -file changes and updating the index.

-

While it is convenient that data is indexed in real time, repeated -indexing can generate a significant load on the system when files such -as email folders change. Also, monitoring large file trees by itself -significantly taxes system resources. You probably do not want to enable -it if your system is short on resources. Periodic indexing is adequate -in most cases.

-

As of RCL 1.24, you can set the -monitordirs -configuration variable to specify that only a subset of your indexed -files will be monitored for instant indexing. In this situation, an -incremental pass on the full tree can be triggered by either restarting -the indexer, or just running recollindex, which will notify the -running process. The recoll GUI also has a menu entry for this.

-
-

Real time indexing: automatic daemon start

-

Under KDE, Gnome and some other desktop environments, the daemon can -automatically started when you log in, by creating a desktop file inside -the ~/.config/autostart directory. This can be done for you by the -RCL GUI. Use the Preferences->Indexing Schedule menu.

-

With older X11 setups, starting the daemon is normally performed as part -of the user session script.

-

The rclmon.sh script can be used to easily start and stop the -daemon. It can be found in the examples directory (typically -/usr/local/[share/]recoll/examples).

-

For example, my out of fashion xdm-based session has a .xsession -script with the following lines at the end:

-
recollconf=$HOME/.recoll-home
-        recolldata=/usr/local/share/recoll
-        RECOLL_CONFDIR=$recollconf $recolldata/examples/rclmon.sh start
-
-        fvwm
-
-
-

The indexing daemon gets started, then the window manager, for which the -session waits.

-

By default the indexing daemon will monitor the state of the X11 -session, and exit when it finishes, it is not necessary to kill it -explicitly. (The X11 server monitoring can be disabled with option --x to recollindex).

-

If you use the daemon completely out of an X11 session, you need to add -option -x to disable X11 session monitoring (else the daemon will -not start).

-
-
-

Real time indexing: miscellaneous details

-

By default, the messages from the indexing daemon will be sent to the -same file as those from the interactive commands (logfilename). You -may want to change this by setting the daemlogfilename and -daemloglevel configuration parameters. Also the log file will only -be truncated when the daemon starts. If the daemon runs permanently, the -log file may grow quite big, depending on the log level.

-

When building RCL, the real time indexing support can be customised -during package configuration with the ---with[out]-fam or --with[out]-inotify options. The default is -currently to include inotify monitoring on systems that support it, and, -as of RCL 1.17, gamin support on FreeBSD.

-
-

Note

-

On Linux systems, monitoring a big tree may need increasing the -resources available to inotify, which are normally defined in -/etc/sysctl.conf.

-
### inotify
-#
-# cat  /proc/sys/fs/inotify/max_queued_events   - 16384
-# cat  /proc/sys/fs/inotify/max_user_instances  - 128
-# cat  /proc/sys/fs/inotify/max_user_watches    - 16384
-#
-# -- Change to:
-#
-fs.inotify.max_queued_events=32768
-fs.inotify.max_user_instances=256
-fs.inotify.max_user_watches=32768
-
-
-

Especially, you will need to trim your tree or adjust the -max_user_watches value if indexing exits with a message about -errno ENOSPC (28) from inotify_add_watch.

-

Note

-

When using the real time monitor, it may happen that some files need -to be indexed, but change so often that they impose an excessive -load for the system.

-

RCL provides a configuration option to specify the minimum time -before which a file, specified by a wildcard pattern, cannot be -reindexed. See the mondelaypatterns parameter in the -configuration section.

-
-
-
-
-
-

Searching

-
-

Searching with the Qt graphical user interface

-

The recoll program provides the main user interface for searching. -It is based on the Qt library.

-

recoll has two search modes:

-
    -
  • Simple search (the default, on the main screen) has a single entry -field where you can enter multiple words.
  • -
  • Advanced search (a panel accessed through the Tools menu or the -toolbox bar icon) has multiple entry fields, which you may use to -build a logical condition, with additional filtering on file type, -location in the file system, modification date, and size.
  • -
-

In most cases, you can enter the terms as you think them, even if they -contain embedded punctuation or other non-textual characters. For -example, RCL can handle things like email addresses, or arbitrary cut -and paste from another text window, punctation and all.

-

The main case where you should enter text differently from how it is -printed is for east-asian languages (Chinese, Japanese, Korean). Words -composed of single or multiple characters should be entered separated by -white space in this case (they would typically be printed without white -space).

-

Some searches can be quite complex, and you may want to re-use them -later, perhaps with some tweaking. RCL versions 1.21 and later can save -and restore searches, using XML files. See Saving and restoring -queries.

- -
-

The default result list

-

After starting a search, a list of results will instantly be displayed -in the main list window.

-

By default, the document list is presented in order of relevance (how -well the system estimates that the document matches the query). You can -sort the result by ascending or descending date by using the vertical -arrows in the toolbar.

-

Clicking on the Preview link for an entry will open an internal -preview window for the document. Further Preview clicks for the same -search will open tabs in the existing preview window. You can use -Shift+Click to force the creation of another preview window, which may -be useful to view the documents side by side. (You can also browse -successive results in a single preview window by typing -Shift+ArrowUp/Down in the window).

-

Clicking the Open link will start an external viewer for the -document. By default, RCL lets the desktop choose the appropriate -application for most document types (there is a short list of -exceptions, see further). If you prefer to completely customize the -choice of applications, you can uncheck the Use desktop preferences -option in the GUI preferences dialog, and click the Choose editor -applications button to adjust the predefined RCL choices. The tool -accepts multiple selections of MIME types (e.g. to set up the editor for -the dozens of office file types).

-

Even when Use desktop preferences is checked, there is a small list of -exceptions, for MIME types where the RCL choice should override the -desktop one. These are applications which are well integrated with RCL, -especially evince for viewing PDF and Postscript files because of its -support for opening the document at a specific page and passing a search -string as an argument. Of course, you can edit the list (in the GUI -preferences) if you would prefer to lose the functionality and use the -standard desktop tool.

-

You may also change the choice of applications by editing the -`mimeview <#RCL.INSTALL.CONFIG.MIMEVIEW>`__ configuration file if -you find this more convenient.

-

Each result entry also has a right-click menu with an Open With entry. -This lets you choose an application from the list of those which -registered with the desktop for the document MIME type.

-

The Preview and Open edit links may not be present for all -entries, meaning that RCL has no configured way to preview a given file -type (which was indexed by name only), or no configured external editor -for the file type. This can sometimes be adjusted simply by tweaking the -`mimemap <#RCL.INSTALL.CONFIG.MIMEMAP>`__ and -`mimeview <#RCL.INSTALL.CONFIG.MIMEVIEW>`__ configuration files (the -latter can be modified with the user preferences dialog).

-

The format of the result list entries is entirely configurable by using -the preference dialog to edit an HTML -fragment.

-

You can click on the Query details link at the top of the results -page to see the query actually performed, after stem expansion and other -processing.

-

Double-clicking on any word inside the result list or a preview window -will insert it into the simple search text.

-

The result list is divided into pages (the size of which you can change -in the preferences). Use the arrow buttons in the toolbar or the links -at the bottom of the page to browse the results.

-
-
No results: the spelling suggestions
-

When a search yields no result, and if the aspell dictionary is -configured, RCL will try to check for misspellings among the query -terms, and will propose lists of replacements. Clicking on one of the -suggestions will replace the word and restart the search. You can hold -any of the modifier keys (Ctrl, Shift, etc.) while clicking if you would -rather stay on the suggestion screen because several terms need -replacement.

-
-
-
The result list right-click menu
-

Apart from the preview and edit links, you can display a pop-up menu by -right-clicking over a paragraph in the result list. This menu has the -following entries:

-
    -
  • Preview
  • -
  • Open
  • -
  • Open With
  • -
  • Run Script
  • -
  • Copy File Name
  • -
  • Copy Url
  • -
  • Save to File
  • -
  • Find similar
  • -
  • Preview Parent document
  • -
  • Open Parent document
  • -
  • Open Snippets Window
  • -
-

The Preview and Open entries do the same thing as the corresponding -links.

-

Open With lets you open the document with one of the applications -claiming to be able to handle its MIME type (the information comes from -the .desktop files in /usr/share/applications).

-

Run Script allows starting an arbitrary command on the result file. It -will only appear for results which are top-level files. See -further for a more detailed description.

-

The Copy File Name and Copy Url copy the relevant data to the clipboard, -for later pasting.

-

Save to File allows saving the contents of a result document to a chosen -file. This entry will only appear if the document does not correspond to -an existing file, but is a subdocument inside such a file (ie: an email -attachment). It is especially useful to extract attachments with no -associated editor.

-

The Open/Preview Parent document entries allow working with the higher -level document (e.g. the email message an attachment comes from). RCL is -sometimes not totally accurate as to what it can or can’t do in this -area. For example the Parent entry will also appear for an email which -is part of an mbox folder file, but you can’t actually visualize the -mbox (there will be an error dialog if you try).

-

If the document is a top-level file, Open Parent will start the default -file manager on the enclosing filesystem directory.

-

The Find similar entry will select a number of relevant term from the -current document and enter them into the simple search field. You can -then start a simple search, with a good chance of finding documents -related to the current result. I can’t remember a single instance where -this function was actually useful to me...

-

The Open Snippets Window entry will only appear for documents which -support page breaks (typically PDF, Postscript, DVI). The snippets -window lists extracts from the document, taken around search terms -occurrences, along with the corresponding page number, as links which -can be used to start the native viewer on the appropriate page. If the -viewer supports it, its search function will also be primed with one of -the search terms.

-
-
-
-

The result table

-

In RCL 1.15 and newer, the results can be displayed in spreadsheet-like -fashion. You can switch to this presentation by clicking the table-like -icon in the toolbar (this is a toggle, click again to restore the list).

-

Clicking on the column headers will allow sorting by the values in the -column. You can click again to invert the order, and use the header -right-click menu to reset sorting to the default relevance order (you -can also use the sort-by-date arrows to do this).

-

Both the list and the table display the same underlying results. The -sort order set from the table is still active if you switch back to the -list mode. You can click twice on a date sort arrow to reset it from -there.

-

The header right-click menu allows adding or deleting columns. The -columns can be resized, and their order can be changed (by dragging). -All the changes are recorded when you quit recoll

-

Hovering over a table row will update the detail area at the bottom of -the window with the corresponding values. You can click the row to -freeze the display. The bottom area is equivalent to a result list -paragraph, with links for starting a preview or a native application, -and an equivalent right-click menu. Typing Esc (the Escape key) will -unfreeze the display.

-
-
-

Running arbitrary commands on result files (1.20 and later)

-

Apart from the Open and Open With operations, which allow starting an -application on a result document (or a temporary copy), based on its -MIME type, it is also possible to run arbitrary commands on results -which are top-level files, using the Run Script entry in the results -pop-up menu.

-

The commands which will appear in the Run Script submenu must be defined -by .desktop files inside the scripts subdirectory of the current -configuration directory.

-

Here follows an example of a .desktop file, which could be named for -example, ~/.recoll/scripts/myscript.desktop (the exact file name -inside the directory is irrelevant):

-
[Desktop Entry]
-Type=Application
-Name=MyFirstScript
-Exec=/home/me/bin/tryscript %F
-MimeType=*/*
-
-
-

The Name attribute defines the label which will appear inside the -Run Script menu. The Exec attribute defines the program to be run, -which does not need to actually be a script, of course. The MimeType -attribute is not used, but needs to exist.

-

The commands defined this way can also be used from links inside the -result paragraph.

-

As an example, it might make sense to write a script which would move -the document to the trash and purge it from the RCL index.

-
-
-

Displaying thumbnails

-

The default format for the result list entries and the detail area of -the result table display an icon for each result document. The icon is -either a generic one determined from the MIME type, or a thumbnail of -the document appearance. Thumbnails are only displayed if found in the -standard freedesktop location, where they would typically have been -created by a file manager.

-

Recoll has no capability to create thumbnails. A relatively simple trick -is to use the Open parent document/folder entry in the result list popup -menu. This should open a file manager window on the containing -directory, which should in turn create the thumbnails (depending on your -settings). Restarting the search should then display the thumbnails.

-

There are also some pointers about thumbnail -generation on the RCL wiki.

-
-
-

The preview window

-

The preview window opens when you first click a Preview link inside -the result list.

-

Subsequent preview requests for a given search open new tabs in the -existing window (except if you hold the Shift key while clicking which -will open a new window for side by side viewing).

-

Starting another search and requesting a preview will create a new -preview window. The old one stays open until you close it.

-

You can close a preview tab by typing Ctrl-W (Ctrl + W) in the window. -Closing the last tab for a window will also close the window.

-

Of course you can also close a preview window by using the window -manager button in the top of the frame.

-

You can display successive or previous documents from the result list -inside a preview tab by typing Shift+Down or Shift+Up (Down and Up are -the arrow keys).

-

A right-click menu in the text area allows switching between displaying -the main text or the contents of fields associated to the document (ie: -author, abtract, etc.). This is especially useful in cases where the -term match did not occur in the main text but in one of the fields. In -the case of images, you can switch between three displays: the image -itself, the image metadata as extracted by exiftool and the fields, -which is the metadata stored in the index.

-

You can print the current preview window contents by typing Ctrl-P (Ctrl -+ P) in the window text.

-
-
Searching inside the preview
-

The preview window has an internal search capability, mostly controlled -by the panel at the bottom of the window, which works in two modes: as a -classical editor incremental search, where we look for the text entered -in the entry zone, or as a way to walk the matches between the document -and the RCL query that found it.

-
-
Incremental text search
-

The preview tabs have an internal incremental search function. You -initiate the search either by typing a / (slash) or CTL-F inside the -text area or by clicking into the Search for: text field and -entering the search string. You can then use the Next and Previous -buttons to find the next/previous occurrence. You can also type F3 -inside the text area to get to the next occurrence.

-

If you have a search string entered and you use Ctrl-Up/Ctrl-Down to -browse the results, the search is initiated for each successive -document. If the string is found, the cursor will be positioned at -the first occurrence of the search string.

-
-
Walking the match lists
-
If the entry area is empty when you click the Next or Previous -buttons, the editor will be scrolled to show the next match to any -search term (the next highlighted zone). If you select a search -group from the dropdown list and click Next or Previous, the match -list for this group will be walked. This is not the same as a text -search, because the occurences will include non-exact matches (as -caused by stemming or wildcards). The search will revert to the text -mode as soon as you edit the entry area.
-
-
-
-
-

The Query Fragments window

-

Selecting the Tools > Query Fragments menu entry will open a window with -radio- and check-buttons which can be used to activate query language -fragments for filtering the current query. This can be useful if you -have frequent reusable selectors, for example, filtering on alternate -directories, or searching just one category of files, not covered by the -standard category selectors.

-

The contents of the window are entirely customizable, and defined by the -contents of the fragbuts.xml file inside the configuration -directory. The sample file distributed with RCL (which you should be -able to find under /usr/share/recoll/examples/fragbuts.xml), -contains an example which filters the results from the WEB history.

-

Here follows an example:

-
<?xml version="1.0" encoding="UTF-8"?>
-
-<fragbuts version="1.0">
-
-<radiobuttons>
-
-<fragbut>
-<label>Include Web Results</label>
-<frag></frag>
-</fragbut>
-
-<fragbut>
-<label>Exclude Web Results</label>
-<frag>-rclbes:BGL</frag>
-</fragbut>
-
-<fragbut>
-<label>Only Web Results</label>
-<frag>rclbes:BGL</frag>
-</fragbut>
-
-</radiobuttons>
-
-<buttons>
-
-<fragbut>
-<label>Year 2010</label>
-<frag>date:2010-01-01/2010-12-31</frag>
-</fragbut>
-
-<fragbut>
-<label>My Great Directory Only</label>
-<frag>dir:/my/great/directory</frag>
-</fragbut>
-
-</buttons>
-</fragbuts>
-
-
-

Each radiobuttons or buttons section defines a line of -checkbuttons or radiobuttons inside the window. Any number of buttons -can be selected, but the radiobuttons in a line are exclusive.

-

Each fragbut section defines the label for a button, and the Query -Language fragment which will be added (as an AND filter) before -performing the query if the button is active.

-

This feature is new in RCL 1.20, and will probably be refined depending -on user feedback.

-
- -
-

The term explorer tool

-

RCL automatically manages the expansion of search terms to their -derivatives (ie: plural/singular, verb inflections). But there are other -cases where the exact search term is not known. For example, you may not -remember the exact spelling, or only know the beginning of the name.

-

The search will only propose replacement terms with spelling variations -when no matching document were found. In some cases, both proper -spellings and mispellings are present in the index, and it may be -interesting to look for them explicitely.

-

The term explorer tool (started from the toolbar icon or from the Term -explorer entry of the Tools menu) can be used to search the full index -terms list. It has three modes of operations:

-
-
Wildcard
-
In this mode of operation, you can enter a search string with -shell-like wildcards (*, ?, []). ie: xapi* would display all index -terms beginning with xapi. (More about wildcards -here).
-
Regular expression
-
This mode will accept a regular expression as input. Example: -word[0-9]+. The expression is implicitely anchored at the beginning. -Ie: press will match pression but not expression. You can use -.*press to match the latter, but be aware that this will cause a -full index term list scan, which can be quite long.
-
Stem expansion
-
This mode will perform the usual stem expansion normally done as -part user input processing. As such it is probably mostly useful to -demonstrate the process.
-
Spelling/Phonetic
-
In this mode, you enter the term as you think it is spelled, and RCL -will do its best to find index terms that sound like your entry. -This mode uses the Aspell spelling application, which must be -installed on your system for things to work (if your documents -contain non-ascii characters, RCL needs an aspell version newer than -0.60 for UTF-8 support). The language which is used to build the -dictionary out of the index terms (which is done at the end of an -indexing pass) is the one defined by your NLS environment. Weird -things will probably happen if languages are mixed up.
-
-

Note that in cases where RCL does not know the beginning of the string -to search for (ie a wildcard expression like *coll), the expansion can -take quite a long time because the full index term list will have to be -processed. The expansion is currently limited at 10000 results for -wildcards and regular expressions. It is possible to change the limit in -the configuration file.

-

Double-clicking on a term in the result list will insert it into the -simple search entry field. You can also cut/paste between the result -list and any entry field (the end of lines will be taken care of).

-
-
-

Multiple indexes

-

See the section describing the use of multiple -indexes for generalities. Only the -aspects concerning the recoll GUI are described here.

-

A recoll program instance is always associated with a specific -index, which is the one to be updated when requested from the File menu, -but it can use any number of RCL indexes for searching. The external -indexes can be selected through the external indexes tab in the -preferences dialog.

-

Index selection is performed in two phases. A set of all usable indexes -must first be defined, and then the subset of indexes to be used for -searching. These parameters are retained across program executions -(there are kept separately for each RCL configuration). The set of all -indexes is usually quite stable, while the active ones might typically -be adjusted quite frequently.

-

The main index (defined by RECOLL_CONFDIR) is always active. If this is -undesirable, you can set up your base configuration to index an empty -directory.

-

When adding a new index to the set, you can select either a RCL -configuration directory, or directly a XAP index directory. In the first -case, the XAP index directory will be obtained from the selected -configuration.

-

As building the set of all indexes can be a little tedious when done -through the user interface, you can use the RECOLL_EXTRA_DBS -environment variable to provide an initial set. This might typically be -set up by a system administrator so that every user does not have to do -it. The variable should define a colon-separated list of index -directories, ie:

-
export RECOLL_EXTRA_DBS=/some/place/xapiandb:/some/other/db
-
-
-

Another environment variable, RECOLL_ACTIVE_EXTRA_DBS allows adding -to the active list of indexes. This variable was suggested and -implemented by a RCL user. It is mostly useful if you use scripts to -mount external volumes with RCL indexes. By using RECOLL_EXTRA_DBS and -RECOLL_ACTIVE_EXTRA_DBS, you can add and activate the index for the -mounted volume when starting recoll.

-

RECOLL_ACTIVE_EXTRA_DBS is available for RCL versions 1.17.2 and -later. A change was made in the same update so that recoll will -automatically deactivate unreachable indexes when starting up.

-
-
-

Document history

-

Documents that you actually view (with the internal preview or an -external tool) are entered into the document history, which is -remembered.

-

You can display the history list by using the Tools/Doc History menu -entry.

-

You can erase the document history by using the Erase document history -entry in the File menu.

-
-
-

Sorting search results and collapsing duplicates

-

The documents in a result list are normally sorted in order of -relevance. It is possible to specify a different sort order, either by -using the vertical arrows in the GUI toolbox to sort by date, or -switching to the result table display and clicking on any header. The -sort order chosen inside the result table remains active if you switch -back to the result list, until you click one of the vertical arrows, -until both are unchecked (you are back to sort by relevance).

-

Sort parameters are remembered between program invocations, but result -sorting is normally always inactive when the program starts. It is -possible to keep the sorting activation state between program -invocations by checking the Remember sort activation state option in the -preferences.

-

It is also possible to hide duplicate entries inside the result list -(documents with the exact same contents as the displayed one). The test -of identity is based on an MD5 hash of the document container, not only -of the text contents (so that ie, a text document with an image added -will not be a duplicate of the text only). Duplicates hiding is -controlled by an entry in the GUI configuration dialog, and is off by -default.

-

As of release 1.19, when a result document does have undisplayed -duplicates, a Dups link will be shown with the result list entry. -Clicking the link will display the paths (URLs + ipaths) for the -duplicate entries.

-
-
-

Search tips, shortcuts

-
-
Terms and search expansion
-

Term completion.

-

Typing Esc Space in the simple search entry field while entering a word -will either complete the current word if its beginning matches a unique -term in the index, or open a window to propose a list of completions.

-

Picking up new terms from result or preview text.

-

Double-clicking on a word in the result list or in a preview window will -copy it to the simple search entry field.

-

Wildcards.

-

Wildcards can be used inside search terms in all forms of searches. -More about wildcards.

-

Automatic suffixes.

-

Words like odt or ods can be automatically turned into query -language ext:xxx clauses. This can be enabled in the Search -preferences panel in the GUI.

-

Disabling stem expansion.

-

Entering a capitalized word in any search field will prevent stem -expansion (no search for gardening if you enter Garden instead -of garden). This is the only case where character case should make a -difference for a RCL search. You can also disable stem expansion or -change the stemming language in the preferences.

-

Finding related documents.

-

Selecting the Find similar documents entry in the result list paragraph -right-click menu will select a set of “interesting” terms from the -current result, and insert them into the simple search entry field. You -can then possibly edit the list and start a search to find documents -which may be apparented to the current result.

-

File names.

-

File names are added as terms during indexing, and you can specify them -as ordinary terms in normal search fields (RCL used to index all -directories in the file path as terms. This has been abandoned as it did -not seem really useful). Alternatively, you can use the specific file -name search which will only look for file names, and may be faster -than the generic search especially when using wildcards.

-
-
-
Working with phrases and proximity
-

Phrases and Proximity searches.

-

A phrase can be looked for by enclosing it in double quotes. Example: -"user manual" will look only for occurrences of user immediately -followed by manual. You can use the This phrase field of the -advanced search dialog to the same effect. Phrases can be entered along -simple terms in all simple or advanced search entry fields (except This -exact phrase).

-

AutoPhrases.

-

This option can be set in the preferences dialog. If it is set, a phrase -will be automatically built and added to simple searches when looking -for Any terms. This will not change radically the results, but will -give a relevance boost to the results where the search terms appear as a -phrase. Ie: searching for virtual reality will still find all -documents where either virtual or reality or both appear, but -those which contain ``virtual

-
-
reality`` should appear sooner in the list.
-

Phrase searches can strongly slow down a query if most of the terms in -the phrase are common. This is why the autophrase option is off by -default for RCL versions before 1.17. As of version 1.17, autophrase -is on by default, but very common terms will be removed from the -constructed phrase. The removal threshold can be adjusted from the -search preferences.

-

Phrases and abbreviations.

-

As of RCL version 1.17, dotted abbreviations like I.B.M. are also -automatically indexed as a word without the dots: IBM. Searching for -the word inside a phrase (ie: "the IBM company") will only match the -dotted abrreviation if you increase the phrase slack (using the advanced -search panel control, or the o query language modifier). Literal -occurences of the word will be matched normally.

-
-
-
Others
-

Using fields.

-

You can use the query language and field -specifications to only search certain parts of documents. This can be -especially helpful with email, for example only searching emails from a -specific originator: search tips from:helpfulgui

-

Ajusting the result table columns.

-

When displaying results in table mode, you can use a right click on the -table headers to activate a pop-up menu which will let you adjust what -columns are displayed. You can drag the column headers to adjust their -order. You can click them to sort by the field displayed in the column. -You can also save the result list in CSV format.

-

Changing the GUI geometry.

-

It is possible to configure the GUI in wide form factor by dragging the -toolbars to one of the sides (their location is remembered between -sessions), and moving the category filters to a menu (can be set in the -Preferences > GUI configuration > User interface panel).

-

Query explanation.

-

You can get an exact description of what the query looked for, including -stem expansion, and Boolean operators used, by clicking on the result -list header.

-

Advanced search history.

-

As of RCL 1.18, you can display any of the last 100 complex searches -performed by using the up and down arrow keys while the advanced search -panel is active.

-

Browsing the result list inside a preview window.

-

Entering Shift-Down or Shift-Up (Shift + an arrow key) in a preview -window will display the next or the previous document from the result -list. Any secondary search currently active will be executed on the new -document.

-

Scrolling the result list from the keyboard.

-

You can use PageUp and PageDown to scroll the result list, Shift+Home to -go back to the first page. These work even while the focus is in the -search entry.

-

Result table: moving the focus to the table.

-

You can use Ctrl-r to move the focus from the search entry to the table, -and then use the arrow keys to change the current row. Ctrl-Shift-s -returns to the search.

-

Result table: open / preview.

-

With the focus in the result table, you can use Ctrl-o to open the -document from the current row, Ctrl-Shift-o to open the document and -close recoll, Ctrl-d to preview the document.

-

Editing a new search while the focus is not in the search entry.

-

You can use the Ctrl-Shift-S shortcut to return the cursor to the search -entry (and select the current search text), while the focus is anywhere -in the main window.

-

Forced opening of a preview window.

-

You can use Shift+Click on a result list Preview link to force the -creation of a preview window instead of a new tab in the existing one.

-

Closing previews.

-

Entering Ctrl-W in a tab will close it (and, for the last tab, close the -preview window). Entering Esc will close the preview window and all its -tabs.

-

Printing previews.

-

Entering Ctrl-P in a preview window will print the currently displayed -text.

-

Quitting.

-

Entering Ctrl-Q almost anywhere will close the application.

-
-
-
-

Saving and restoring queries (1.21 and later)

-

Both simple and advanced query dialogs save recent history, but the -amount is limited: old queries will eventually be forgotten. Also, -important queries may be difficult to find among others. This is why -both types of queries can also be explicitely saved to files, from the -GUI menus: File > Save last query / Load last query

-

The default location for saved queries is a subdirectory of the current -configuration directory, but saved queries are ordinary files and can be -written or moved anywhere.

-

Some of the saved query parameters are part of the preferences (e.g. -autophrase or the active external indexes), and may differ when the -query is loaded from the time it was saved. In this case, RCL will warn -of the differences, but will not change the user preferences.

-
-
-

Customizing the search interface

-

You can customize some aspects of the search interface by using the GUI -configuration entry in the Preferences menu.

-

There are several tabs in the dialog, dealing with the interface itself, -the parameters used for searching and returning results, and what -indexes are searched.

-

User interface parameters:.

-
    -
  • Highlight color for query terms: Terms from the user query are -highlighted in the result list samples and the preview window. The -color can be chosen here. Any Qt color string should work (ie -red, #ff0000). The default is blue.

    -
  • -
  • Style sheet: The name of a Qt style sheet text file which is applied -to the whole Recoll application on startup. The default value is -empty, but there is a skeleton style sheet (recoll.qss) inside -the /usr/share/recoll/examples directory. Using a style sheet, -you can change most recoll graphical parameters: colors, fonts, -etc. See the sample file for a few simple examples.

    -

    You should be aware that parameters (e.g.: the background color) set -inside the RCL GUI style sheet will override global system -preferences, with possible strange side effects: for example if you -set the foreground to a light color and the background to a dark one -in the desktop preferences, but only the background is set inside the -RCL style sheet, and it is light too, then text will appear -light-on-light inside the RCL GUI.

    -
  • -
  • Maximum text size highlighted for preview Inserting highlights on -search term inside the text before inserting it in the preview window -involves quite a lot of processing, and can be disabled over the -given text size to speed up loading.

    -
  • -
  • Prefer HTML to plain text for preview if set, Recoll will display -HTML as such inside the preview window. If this causes problems with -the Qt HTML display, you can uncheck it to display the plain text -version instead.

    -
  • -
  • Activate links in preview if set, Recoll will turn HTTP links found -inside plain text into proper HTML anchors, and clicking a link -inside a preview window will start the default browser on the link -target.

    -
  • -
  • Plain text to HTML line style: when displaying plain text inside the -preview window, RCL tries to preserve some of the original text line -breaks and indentation. It can either use PRE HTML tags, which will -well preserve the indentation but will force horizontal scrolling for -long lines, or use BR tags to break at the original line breaks, -which will let the editor introduce other line breaks according to -the window width, but will lose some of the original indentation. The -third option has been available in recent releases and is probably -now the best one: use PRE tags with line wrapping.

    -
  • -
  • Choose editor application: this opens a dialog which allows you to -select the application to be used to open each MIME type. The default -is to use the xdg-open utility, but you can use this dialog to -override it, setting exceptions for MIME types that will still be -opened according to RCL preferences. This is useful for passing -parameters like page numbers or search strings to applications that -support them (e.g. evince). This cannot be done with xdg-open -which only supports passing one parameter.

    -
  • -
  • Disable Qt autocompletion in search entry: this will disable the -completion popup. Il will only appear, and display the full history, -either if you enter only white space in the search area, or if you -click the clock button on the right of the area.

    -
  • -
  • Document filter choice style: this will let you choose if the -document categories are displayed as a list or a set of buttons, or a -menu.

    -
  • -
  • Start with simple search mode: this lets you choose the value of the -simple search type on program startup. Either a fixed value (e.g. -Query Language, or the value in use when the program last exited.

    -
  • -
  • Start with advanced search dialog open: If you use this dialog -frequently, checking the entries will get it to open when recoll -starts.

    -
  • -
  • Remember sort activation state if set, Recoll will remember the sort -tool stat between invocations. It normally starts with sorting -disabled.

    -
  • -
-

Result list parameters:.

-
    -
  • Number of results in a result page
  • -
  • Result list font: There is quite a lot of information shown in the -result list, and you may want to customize the font and/or font size. -The rest of the fonts used by RCL are determined by your generic Qt -config (try the qtconfig command).
  • -
  • Edit result list paragraph format string: allows you to change the -presentation of each result list entry. See the result list -customisation section.
  • -
  • Edit result page HTML header insert: allows you to define text -inserted at the end of the result page HTML header. More detail in -the result list customisation -section.
  • -
  • Date format: allows specifying the format used for displaying dates -inside the result list. This should be specified as an strftime() -string (man strftime).
  • -
  • Abstract snippet separator: for synthetic abstracts built from index -data, which are usually made of several snippets from different parts -of the document, this defines the snippet separator, an ellipsis by -default.
  • -
-

Search parameters:.

-
    -
  • Hide duplicate results: decides if result list entries are shown for -identical documents found in different places.

    -
  • -
  • Stemming language: stemming obviously depends on the document’s -language. This listbox will let you chose among the stemming -databases which were built during indexing (this is set in the main -configuration file), or later -added with ``recollindex

    -
    -

    -s`` (See the recollindex manual). Stemming languages

    -
    -

    which are dynamically added will be deleted at the next indexing pass -unless they are also added in the configuration file.

    -
  • -
  • Automatically add phrase to simple searches: a phrase will be -automatically built and added to simple searches when looking for -``Any

    -
    -

    terms``. This will give a relevance boost to the

    -
    -

    results where the search terms appear as a phrase (consecutive and in -order).

    -
  • -
  • Autophrase term frequency threshold percentage: very frequent terms -should not be included in automatic phrase searches for performance -reasons. The parameter defines the cutoff percentage (percentage of -the documents where the term appears).

    -
  • -
  • Replace abstracts from documents: this decides if we should -synthesize and display an abstract in place of an explicit abstract -found within the document itself.

    -
  • -
  • Dynamically build abstracts: this decides if RCL tries to build -document abstracts (lists of snippets) when displaying the result -list. Abstracts are constructed by taking context from the document -information, around the search terms.

    -
  • -
  • Synthetic abstract size: adjust to taste...

    -
  • -
  • Synthetic abstract context words: how many words should be displayed -around each term occurrence.

    -
  • -
  • Query language magic file name suffixes: a list of words which -automatically get turned into ext:xxx file name suffix clauses -when starting a query language query (ie: ``doc xls

    -
    -

    xlsx...``). This will save some typing for people who

    -
    -

    use file types a lot when querying.

    -
  • -
-

External indexes:.

-

This panel will let you browse for additional indexes that you may want -to search. External indexes are designated by their database directory -(ie: /home/someothergui/.recoll/xapiandb, -/usr/local/recollglobal/xapiandb).

-

Once entered, the indexes will appear in the External indexes list, and -you can chose which ones you want to use at any moment by checking or -unchecking their entries.

-

Your main database (the one the current configuration indexes to), is -always implicitly active. If this is not desirable, you can set up your -configuration so that it indexes, for example, an empty directory. An -alternative indexer may also need to implement a way of purging the -index from stale data,

-
-
The result list format
-

Newer versions of Recoll (from 1.17) normally use WebKit HTML widgets -for the result list and the snippets -window (this may be -disabled at build time). Total customisation is possible with full -support for CSS and Javascript. Conversely, there are limits to what you -can do with the older Qt QTextBrowser, but still, it is possible to -decide what data each result will contain, and how it will be displayed.

-

The result list presentation can be exhaustively customized by adjusting -two elements:

-
    -
  • The paragraph format
  • -
  • HTML code inside the header section. For versions 1.21 and later, -this is also used for the snippets -window
  • -
-

The paragraph format and the header fragment can be edited from the -Result list tab of the GUI configuration.

-

The header fragment is used both for the result list and the snippets -window. The snippets list is a table and has a snippets class -attribute. Each paragraph in the result list is a table, with class -respar, but this can be changed by editing the paragraph format.

-

There are a few examples on the page about customising the result -list on the RCL web site.

-
-
The paragraph format
-

This is an arbitrary HTML string where the following printf-like % -substitutions will be performed:

-
    -
  • %A.

    -

    Abstract

    -
  • -
  • %D.

    -

    Date

    -
  • -
  • %I.

    -

    Icon image name. This is normally determined from the MIME type. The -associations are defined inside the `mimeconf configuration -file <#RCL.INSTALL.CONFIG.MIMECONF>`__. If a thumbnail for the file -is found at the standard Freedesktop location, this will be displayed -instead.

    -
  • -
  • %K.

    -

    Keywords (if any)

    -
  • -
  • %L.

    -

    Precooked Preview, Edit, and possibly Snippets links

    -
  • -
  • %M.

    -

    MIME type

    -
  • -
  • %N.

    -

    result Number inside the result page

    -
  • -
  • %P.

    -

    Parent folder Url. In the case of an embedded document, this is the -parent folder for the top level container file.

    -
  • -
  • %R.

    -

    Relevance percentage

    -
  • -
  • %S.

    -

    Size information

    -
  • -
  • %T.

    -

    Title or Filename if not set.

    -
  • -
  • %t.

    -

    Title or empty.

    -
  • -
  • %(filename).

    -

    File name.

    -
  • -
  • %U.

    -

    Url

    -
  • -
-

The format of the Preview, Edit, and Snippets links is -<a href="P%N">, <a href="E%N"> and <a href="A%N"> where -docnum (%N) expands to the document number inside the result page).

-

A link target defined as "F%N" will open the document corresponding -to the %P parent folder expansion, usually creating a file manager -window on the folder where the container file resides. E.g.:

-
<a href="F%N">%P</a>
-
-
-

A link target defined as R%N|scriptname will run the corresponding -script on the result file (if the document is embedded, the script will -be started on the top-level parent). See the section about defining -scripts.

-

In addition to the predefined values above, all strings like -%(fieldname) will be replaced by the value of the field named -fieldname for this document. Only stored fields can be accessed in -this way, the value of indexed but not stored fields is not known at -this point in the search process (see field -configuration). There are currently very few -fields stored by default, apart from the values above (only author -and filename), so this feature will need some custom local -configuration to be useful. An example candidate would be the -recipient field which is generated by the message input handlers.

-

The default value for the paragraph format string is:

-
"<table class=\"respar\">\n"
-"<tr>\n"
-"<td><a href='%U'><img src='%I' width='64'></a></td>\n"
-"<td>%L &nbsp;<i>%S</i> &nbsp;&nbsp;<b>%T</b><br>\n"
-"<span style='white-space:nowrap'><i>%M</i>&nbsp;%D</span>&nbsp;&nbsp;&nbsp; <i>%U</i>&nbsp;%i<br>\n"
-"%A %K</td>\n"
-"</tr></table>\n"
-
-
-

You may, for example, try the following for a more web-like experience:

-
<u><b><a href="P%N">%T</a></b></u><br>
-%A<font color=#008000>%U - %S</font> - %L
-
-
-

Note that the P%N link in the above paragraph makes the title a preview -link. Or the clean looking:

-
<img src="%I" align="left">%L <font color="#900000">%R</font>
-&nbsp;&nbsp;<b>%T&</b><br>%S&nbsp;
-<font color="#808080"><i>%U</i></font>
-<table bgcolor="#e0e0e0">
-<tr><td><div>%A</div></td></tr>
-</table>%K
-
-
-

These samples, and some others are on the web site, with pictures to -show how they look.

-

It is also possible to define the value of the snippet separator inside -the abstract section.

-
-
-
-
-
-

Searching with the KDE KIO slave

-
-

What’s this

-

The RCL KIO slave allows performing a RCL search by entering an -appropriate URL in a KDE open dialog, or with an HTML-based interface -displayed in Konqueror.

-

The HTML-based interface is similar to the Qt-based interface, but -slightly less powerful for now. Its advantage is that you can perform -your search while staying fully within the KDE framework: drag and drop -from the result list works normally and you have your normal choice of -applications for opening files.

-

The alternative interface uses a directory view of search results. Due -to limitations in the current KIO slave interface, it is currently not -obviously useful (to me).

-

The interface is described in more detail inside a help file which you -can access by entering recoll:/ inside the konqueror URL line -(this works only if the recoll KIO slave has been previously installed).

-

The instructions for building this module are located in the source -tree. See: kde/kio/recoll/00README.txt. Some Linux distributions do -package the kio-recoll module, so check before diving into the build -process, maybe it’s already out there ready for one-click installation.

-
-
-

Searchable documents

-

As a sample application, the RCL KIO slave could allow preparing a set -of HTML documents (for example a manual) so that they become their own -search interface inside konqueror.

-

This can be done by either explicitly inserting -<a href="recoll://..."> links around some document areas, or -automatically by adding a very small javascript program to the -documents, like the following example, which would initiate a search by -double-clicking any term:

-
<script language="JavaScript">
-        function recollsearch() {
-        var t = document.getSelection();
-        window.location.href = 'recoll://search/query?qtp=a&p=0&q=' +
-        encodeURIComponent(t);
-        }
-        </script>
-        ....
-        <body ondblclick="recollsearch()">
-
-
-
-
-
-

Searching on the command line

-

There are several ways to obtain search results as a text stream, -without a graphical interface:

-
    -
  • By passing option -t to the recoll program, or by calling it -as recollq (through a link).
  • -
  • By using the recollq program.
  • -
  • By writing a custom Python program, using the Recoll Python -API.
  • -
-

The first two methods work in the same way and accept/need the same -arguments (except for the additional -t to recoll). The query to -be executed is specified as command line arguments.

-

recollq is not built by default. You can use the Makefile in the -query directory to build it. This is a very simple program, and if -you can program a little c++, you may find it useful to taylor its -output format to your needs. Not that recollq is only really useful on -systems where the Qt libraries (or even the X11 ones) are not available. -Otherwise, just use ``recoll

-
-
-t``, which takes the exact same parameters and options which are
-

described for recollq

-

recollq has a man page (not installed by default, look in the -doc/man directory). The Usage string is as follows:

-
recollq: usage:
--P: Show the date span for all the documents present in the index
-[-o|-a|-f] [-q] <query string>
-Runs a recoll query and displays result lines.
-Default: will interpret the argument(s) as a xesam query string
-query may be like:
-implicit AND, Exclusion, field spec:    t1 -t2 title:t3
-OR has priority: t1 OR t2 t3 OR t4 means (t1 OR t2) AND (t3 OR t4)
-Phrase: "t1 t2" (needs additional quoting on cmd line)
--o Emulate the GUI simple search in ANY TERM mode
--a Emulate the GUI simple search in ALL TERMS mode
--f Emulate the GUI simple search in filename mode
--q is just ignored (compatibility with the recoll GUI command line)
-Common options:
--c <configdir> : specify config directory, overriding $RECOLL_CONFDIR
--d also dump file contents
--n [first-]<cnt> define the result slice. The default value for [first]
-is 0. Without the option, the default max count is 2000.
-Use n=0 for no limit
--b : basic. Just output urls, no mime types or titles
--Q : no result lines, just the processed query and result count
--m : dump the whole document meta[] array for each result
--A : output the document abstracts
--S fld : sort by field <fld>
--s stemlang : set stemming language to use (must exist in index...)
-Use -s "" to turn off stem expansion
--D : sort descending
--i <dbdir> : additional index, several can be given
--e use url encoding (%xx) for urls
--F <field name list> : output exactly these fields for each result.
-The field values are encoded in base64, output in one line and
-separated by one space character. This is the recommended format
-for use by other programs. Use a normal query with option -m to
-see the field names.
-
-
-

Sample execution:

-
recollq 'ilur -nautique mime:text/html'
-      Recoll query: ((((ilur:(wqf=11) OR ilurs) AND_NOT (nautique:(wqf=11)
-      OR nautiques OR nautiqu OR nautiquement)) FILTER Ttext/html))
-      4 results
-      text/html       [file:///Users/uncrypted-dockes/projets/bateaux/ilur/comptes.html]      [comptes.html]  18593   bytes
-      text/html       [file:///Users/uncrypted-dockes/projets/nautique/webnautique/articles/ilur1/index.html] [Constructio...
-      text/html       [file:///Users/uncrypted-dockes/projets/pagepers/index.html]    [psxtcl/writemime/recoll]...
-      text/html       [file:///Users/uncrypted-dockes/projets/bateaux/ilur/factEtCie/recu-chasse-maree....
-
-
-
-
-

Using Synonyms (1.22)

-

Term synonyms:.

-

there are a number of ways to use term synonyms for searching text:

-
    -
  • At index creation time, they can be used to alter the indexed terms, -either increasing or decreasing their number, by expanding the -original terms to all synonyms, or by reducing all synonym terms to a -canonical one.
  • -
  • At query time, they can be used to match texts containing terms which -are synonyms of the ones specified by the user, either by expanding -the query for all synonyms, or by reducing the user entry to -canonical terms (the latter only works if the corresponding -processing has been performed while creating the index).
  • -
-

RCL only uses synonyms at query time. A user query term which part of a -synonym group will be optionally expanded into an OR query for all -terms in the group.

-

Synonym groups are defined inside ordinary text files. Each line in the -file defines a group.

-

Example:

-
hi hello "good morning"
-
-# not sure about "au revoir" though. Is this english ?
-bye goodbye "see you" \
-"au revoir"
-
-
-

As usual, lines beginning with a # are comments, empty lines are -ignored, and lines can be continued by ending them with a backslash.

-

Multi-word synonyms are supported, but be aware that these will generate -phrase queries, which may degrade performance and will disable stemming -expansion for the phrase terms.

-

The synonyms file can be specified in the Search parameters tab of the -GUI configuration Preferences menu entry, or as an option for -command-line searches.

-

Once the file is defined, the use of synonyms can be enabled or disabled -directly from the Preferences menu.

-

The synonyms are searched for matches with user terms after the latter -are stem-expanded, but the contents of the synonyms file itself is not -subjected to stem expansion. This means that a match will not be found -if the form present in the synonyms file is not present anywhere in the -document set.

-

The synonyms function is probably not going to help you find your -letters to Mr. Smith. It is best used for domain-specific searches. For -example, it was initially suggested by a user performing searches among -historical documents: the synonyms file would contains nicknames and -aliases for each of the persons of interest.

-
-
-

Path translations

-

In some cases, the document paths stored inside the index do not match -the actual ones, so that document previews and accesses will fail. This -can occur in a number of circumstances:

-
    -
  • When using multiple indexes it is a relatively common occurrence that -some will actually reside on a remote volume, for exemple mounted via -NFS. In this case, the paths used to access the documents on the -local machine are not necessarily the same than the ones used while -indexing on the remote machine. For example, /home/me may have -been used as a topdirs elements while indexing, but the directory -might be mounted as /net/server/home/me on the local machine.
  • -
  • The case may also occur with removable disks. It is perfectly -possible to configure an index to live with the documents on the -removable disk, but it may happen that the disk is not mounted at the -same place so that the documents paths from the index are invalid.
  • -
  • As a last exemple, one could imagine that a big directory has been -moved, but that it is currently inconvenient to run the indexer.
  • -
-

RCL has a facility for rewriting access paths when extracting the data -from the index. The translations can be defined for the main index and -for any additional query index.

-

The path translation facility will be useful whenever the documents -paths seen by the indexer are not the same as the ones which should be -used at query time.

-

In the above NFS example, RCL could be instructed to rewrite any -file:///home/me URL from the index to -file:///net/server/home/me, allowing accesses from the client.

-

The translations are defined in the -`ptrans <#RCL.INSTALL.CONFIG.PTRANS>`__ configuration file, which -can be edited by hand or from the GUI external indexes configuration -dialog: Preferences > External index dialog, then click the Paths -translations button on the right below the index list.

-
-

Note

-

Due to a current bug, the GUI must be restarted after changing the -ptrans values (even when they were changed from the GUI).

-
-
-
-

The query language

-

The query language processor is activated in the GUI simple search entry -when the search mode selector is set to Query Language. It can also be -used with the KIO slave or the command line search. It broadly has the -same capabilities as the complex search interface in the GUI.

-

The language was based on the now defunct -Xesam user -search language specification.

-

If the results of a query language search puzzle you and you doubt what -has been actually searched for, you can use the GUI Show Query link -at the top of the result list to check the exact query which was finally -executed by Xapian.

-

Here follows a sample request that we are going to explain:

-
author:"john doe" Beatles OR Lennon Live OR Unplugged -potatoes
-
-
-

This would search for all documents with John Doe appearing as a phrase -in the author field (exactly what this is would depend on the document -type, ie: the From: header, for an email message), and containing -either beatles or lennon and either live or unplugged but not potatoes -(in any part of the document).

-

An element is composed of an optional field specification, and a value, -separated by a colon (the field separator is the last colon in the -element). Examples: Eugenie, author:balzac, dc:title:grandet -dc:title:”eugenie grandet”

-

The colon, if present, means “contains”. Xesam defines other relations, -which are mostly unsupported for now (except in special cases, described -further down).

-

All elements in the search entry are normally combined with an implicit -AND. It is possible to specify that elements be OR’ed instead, as in -Beatles OR Lennon. The OR must be entered literally (capitals), -and it has priority over the AND associations: word1 word2 OR word3 -means word1 AND (word2 OR word3) not (word1 AND word2) OR word3.

-

RCL versions 1.21 and later, allow using parentheses to group elements, -which will sometimes make things clearer, and may allow expressing -combinations which would have been difficult otherwise.

-

An element preceded by a - specifies a term that should not -appear.

-

As usual, words inside quotes define a phrase (the order of words is -significant), so that title:”prejudice pride” is not the same as -title:prejudice title:pride, and is unlikely to find a result.

-

Words inside phrases and capitalized words are not stem-expanded. -Wildcards may be used anywhere inside a term. Specifying a wild-card on -the left of a term can produce a very slow search (or even an incorrect -one if the expansion is truncated because of excessive size). Also see -More about wildcards.

-

To save you some typing, recent RCL versions (1.20 and later) interpret -a comma-separated list of terms as an AND list inside the field. Use -slash characters (‘/’) for an OR list. No white space is allowed. So

-
author:john,lennon
-
-
-

will search for documents with john and lennon inside the -author field (in any order), and

-
author:john/ringo
-
-
-

would search for john or ringo.

-

Modifiers can be set on a double-quote value, for example to specify a -proximity search (unordered). See the modifier -section. No space must separate the -final double-quote and the modifiers value, e.g. “two one”po10

-

RCL currently manages the following default fields:

-
    -
  • title, subject or caption are synonyms which specify data -to be searched for in the document title or subject.
  • -
  • author or from for searching the documents originators.
  • -
  • recipient or to for searching the documents recipients.
  • -
  • keyword for searching the document-specified keywords (few -documents actually have any).
  • -
  • filename for the document’s file name. This is not necessarily -set for all documents: internal documents contained inside a compound -one (for example an EPUB section) do not inherit the container file -name any more, this was replaced by an explicit field (see next). -Sub-documents can still have a specific filename, if it is -implied by the document format, for example the attachment file name -for an email attachment.
  • -
  • containerfilename. This is set for all documents, both top-level -and contained sub-documents, and is always the name of the filesystem -directory entry which contains the data. The terms from this field -can only be matched by an explicit field specification (as opposed to -terms from filename which are also indexed as general document -content). This avoids getting matches for all the sub-documents when -searching for the container file name.
  • -
  • ext specifies the file name extension (Ex: ext:html)
  • -
-

RCL 1.20 and later have a way to specify aliases for the field names, -which will save typing, for example by aliasing filename to fn or -containerfilename to cfn. See the section about the ``fields` -file <#RCL.INSTALL.CONFIG.FIELDS>`__

-

The document input handlers used while indexing have the possibility to -create other fields with arbitrary names, and aliases may be defined in -the configuration, so that the exact field search possibilities may be -different for you if someone took care of the customisation.

-

The field syntax also supports a few field-like, but special, criteria:

-
    -
  • dir for filtering the results on file location (Ex: -dir:/home/me/somedir). -dir also works to find results not in -the specified directory (release >= 1.15.8). Tilde expansion will be -performed as usual (except for a bug in versions 1.19 to 1.19.11p1). -Wildcards will be expanded, but please have a -look at an important limitation of -wildcards in path filters.

    -

    Relative paths also make sense, for example, dir:share/doc would -match either /usr/share/doc or /usr/local/share/doc

    -

    Several dir clauses can be specified, both positive and negative. -For example the following makes sense:

    -
    dir:recoll dir:src -dir:utils -dir:common
    -
    -
    -

    This would select results which have both recoll and src in -the path (in any order), and which have not either utils or -common.

    -

    You can also use OR conjunctions with dir: clauses.

    -

    A special aspect of dir clauses is that the values in the index -are not transcoded to UTF-8, and never lower-cased or unaccented, but -stored as binary. This means that you need to enter the values in the -exact lower or upper case, and that searches for names with -diacritics may sometimes be impossible because of character set -conversion issues. Non-ASCII UNIX file paths are an unending source -of trouble and are best avoided.

    -

    You need to use double-quotes around the path value if it contains -space characters.

    -
  • -
  • size for filtering the results on file size. Example: -size<10000. You can use <, > or = as operators. You -can specify a range like the following: size>100 size<1000. The -usual k/K, m/M, g/G, t/T can be used as (decimal) multipliers. -Ex: size>1k to search for files bigger than 1000 bytes.

    -
  • -
  • date for searching or filtering on dates. The syntax for the -argument is based on the ISO8601 standard for dates and time -intervals. Only dates are supported, no times. The general syntax is -2 elements separated by a / character. Each element can be a date -or a period of time. Periods are specified as -PnYnMnD. The n numbers are the respective -numbers of years, months or days, any of which may be missing. Dates -are specified as YYYY-MM-DD. The days and months parts may be -missing. If the / is present but an element is missing, the -missing element is interpreted as the lowest or highest date in the -index. Examples:

    -
      -
    • 2001-03-01/2002-05-01 the basic syntax for an interval of -dates.
    • -
    • 2001-03-01/P1Y2M the same specified with a period.
    • -
    • 2001/ from the beginning of 2001 to the latest date in the -index.
    • -
    • 2001 the whole year of 2001
    • -
    • P2D/ means 2 days ago up to now if there are no documents with -dates in the future.
    • -
    • /2003 all documents from 2003 or older.
    • -
    -

    Periods can also be specified with small letters (ie: p2y).

    -
  • -
  • mime or format for specifying the MIME type. These clauses -are processed besides the normal Boolean logic of the search. -Multiple values will be OR’ed (instead of the normal AND). You can -specify types to be excluded, with the usual -, and use -wildcards. Example: mime:text/* -mime:text/plain Specifying an -explicit boolean operator before a mime specification is not -supported and will produce strange results.

    -
  • -
  • type or rclcat for specifying the category (as in -text/media/presentation/etc.). The classification of MIME types in -categories is defined in the RCL configuration (mimeconf), and -can be modified or extended. The default category names are those -which permit filtering results in the main GUI screen. Categories are -OR’ed like MIME types above, and can be negated with -.

    -
    -

    Note

    -

    mime, rclcat, size and date criteria always affect -the whole query (they are applied as a final filter), even if set -with other terms inside a parenthese.

    -

    Note

    -

    mime (or the equivalent rclcat) is the only field with an -OR default. You do need to use OR with ext terms for -example.

    -
    -
  • -
-
-

Range clauses

-

RCL 1.24 and later support range clauses on fields which have been -configured to support it. No default field uses them currently, so this -paragraph is only interesting if you modified the fields configuration -and possibly use a custom input handler.

-

A range clause looks like one of the following:

-
myfield:small..big
-myfield:small..
-myfield:..big
-
-
-

The nature of the clause is indicated by the two dots .., and the -effect is to filter the results for which the myfield value is in the -possibly open-ended interval.

-

See the section about the `fields configuration -file <#RCL.INSTALL.CONFIG.FIELDS>`__ for the details of configuring a -field for range searches (list them in the [values] section).

-
-
-

Modifiers

-

Some characters are recognized as search modifiers when found -immediately after the closing double quote of a phrase, as in -"some term"modifierchars. The actual “phrase” can be a single term -of course. Supported modifiers:

-
    -
  • l can be used to turn off stemming (mostly makes sense with p -because stemming is off by default for phrases).
  • -
  • s can be used to turn off synonym expansion, if a synonyms file -is in place (only for RCL 1.22 and later).
  • -
  • o can be used to specify a “slack” for phrase and proximity -searches: the number of additional terms that may be found between -the specified ones. If o is followed by an integer number, this -is the slack, else the default is 10.
  • -
  • p can be used to turn the default phrase search into a proximity -one (unordered). Example: "order any in"p
  • -
  • C will turn on case sensitivity (if the index supports it).
  • -
  • D will turn on diacritics sensitivity (if the index supports it).
  • -
  • A weight can be specified for a query element by specifying a decimal -value at the start of the modifiers. Example: "Important"2.5.
  • -
-
-
-
-

Search case and diacritics sensitivity

-

For RCL versions 1.18 and later, and when working with a raw index -(not the default), searches can be sensitive to character case and -diacritics. How this happens is controlled by configuration variables -and what search data is entered.

-

The general default is that searches entered without upper-case or -accented characters are insensitive to case and diacritics. An entry of -resume will match any of Resume, RESUME, résumé, -Résumé etc.

-

Two configuration variables can automate switching on sensitivity (they -were documented but actually did nothing until RCL 1.22):

-
-
autodiacsens
-
If this is set, search sensitivity to diacritics will be turned on -as soon as an accented character exists in a search term. When the -variable is set to true, resume will start a -diacritics-unsensitive search, but résumé will be matched -exactly. The default value is false.
-
autocasesens
-
If this is set, search sensitivity to character case will be turned -on as soon as an upper-case character exists in a search term -except for the first one. When the variable is set to true, us -or Us will start a diacritics-unsensitive search, but US -will be matched exactly. The default value is true (contrary to -autodiacsens).
-
-

As in the past, capitalizing the first letter of a word will turn off -its stem expansion and have no effect on case-sensitivity.

-

You can also explicitely activate case and diacritics sensitivity by -using modifiers with the query language. C will make the term -case-sensitive, and D will make it diacritics-sensitive. Examples:

-
"us"C
-
-
-

will search for the term us exactly (Us will not be a match).

-
"resume"D
-
-
-

will search for the term resume exactly (résumé will not be a -match).

-

When either case or diacritics sensitivity is activated, stem expansion -is turned off. Having both does not make much sense.

-
-
-

Anchored searches and wildcards

-

Some special characters are interpreted by RCL in search strings to -expand or specialize the search. Wildcards expand a root term in -controlled ways. Anchor characters can restrict a search to succeed only -if the match is found at or near the beginning of the document or one of -its fields.

-
-

More about wildcards

-

All words entered in RCL search fields will be processed for wildcard -expansion before the request is finally executed.

-

The wildcard characters are:

-
    -
  • * which matches 0 or more characters.
  • -
  • ? which matches a single character.
  • -
  • [] which allow defining sets of characters to be matched (ex: -[abc] matches a single character which may be ‘a’ or -‘b’ or ‘c’, [0-9] matches any number.
  • -
-

You should be aware of a few things when using wildcards.

-
    -
  • Using a wildcard character at the beginning of a word can make for a -slow search because RCL will have to scan the whole index term list -to find the matches. However, this is much less a problem for field -searches, and queries like author:*@domain.com can sometimes be very -useful.
  • -
  • For RCL version 18 only, when working with a raw index (preserving -character case and diacritics), the literal part of a wildcard -expression will be matched exactly for case and diacritics. This is -not true any more for versions 19 and later.
  • -
  • Using a * at the end of a word can produce more matches than you -would think, and strange search results. You can use the term -explorer tool to check what -completions exist for a given term. You can also see exactly what -search was performed by clicking on the link at the top of the result -list. In general, for natural language terms, stem expansion will -produce better results than an ending * (stem expansion is turned -off when any wildcard character appears in the term).
  • -
-
-
Wildcards and path filtering
-

Due to the way that RCL processes wildcards inside dir path -filtering clauses, they will have a multiplicative effect on the query -size. A clause containg wildcards in several paths elements, like, for -example, dir:/home/me/*/*/docdir, will almost certainly fail if -your indexed tree is of any realistic size.

-

Depending on the case, you may be able to work around the issue by -specifying the paths elements more narrowly, with a constant prefix, or -by using 2 separate dir: clauses instead of multiple wildcards, as -in dir:/home/me dir:docdir. The latter query is not equivalent -to the initial one because it does not specify a number of directory -levels, but that’s the best we can do (and it may be actually more -useful in some cases).

-
-
-
-

Anchored searches

-

Two characters are used to specify that a search hit should occur at the -beginning or at the end of the text. ^ at the beginning of a term or -phrase constrains the search to happen at the start, $ at the end -force it to happen at the end.

-

As this function is implemented as a phrase search it is possible to -specify a maximum distance at which the hit should occur, either through -the controls of the advanced search panel, or using the query language, -for example, as in:

-
"^someterm"o10
-
-
-

which would force someterm to be found within 10 terms of the start -of the text. This can be combined with a field search as in -somefield:"^someterm"o10 or somefield:someterm$.

-

This feature can also be used with an actual phrase search, but in this -case, the distance applies to the whole phrase and anchor, so that, for -example, ``bla bla my unexpected

-
-
term`` at the beginning of the text would be a match for
-

"^my term"o5.

-

Anchored searches can be very useful for searches inside somewhat -structured documents like scientific articles, in case explicit metadata -has not been supplied (a most frequent case), for example for looking -for matches inside the abstract or the list of authors (which occur at -the top of the document).

-
-
-
-

Desktop integration

-

Being independant of the desktop type has its drawbacks: RCL desktop -integration is minimal. However there are a few tools available:

- -

Here follow a few other things that may help.

-
-

Hotkeying recoll

-

It is surprisingly convenient to be able to show or hide the RCL GUI -with a single keystroke. Recoll comes with a small Python script, based -on the libwnck window manager interface library, which will allow you to -do just this. The detailed instructions are on this wiki -page.

-
-
-

The KDE Kicker Recoll applet

-

This is probably obsolete now. Anyway:

-

The RCL source tree contains the source code to the recoll_applet, a -small application derived from the find_applet. This can be used to add -a small RCL launcher to the KDE panel.

-

The applet is not automatically built with the main RCL programs, nor is -it included with the main source distribution (because the KDE build -boilerplate makes it relatively big). You can download its source from -the recoll.org download page. Use the omnipotent -configure;make;make install incantation to build and install.

-

You can then add the applet to the panel by right-clicking the panel and -choosing the Add applet entry.

-

The recoll_applet has a small text window where you can type a RCL -query (in query language form), and an icon which can be used to -restrict the search to certain types of files. It is quite primitive, -and launches a new recoll GUI instance every time (even if it is already -running). You may find it useful anyway.

-
-
-
-
-

Removable volumes

-

RCL used to have no support for indexing removable volumes (portable -disks, USB keys, etc.). Recent versions have improved the situation and -support indexing removable volumes in two different ways:

-
    -
  • By storing a volume index on the volume itself (RCL 1.24).
  • -
  • By indexing the volume in the main, fixed, index, and ensuring that -the volume data is not purged if the indexing runs while the volume -is mounted. (RCL 1.25.2).
  • -
-
-

Indexing removable volumes in the main index

-

As of version 1.25.2, RCL has a simple way to ensure that the index data -for an absent volume will not be purged: the volume mount point must be -a member of the topdirs list, and the mount directory must be empty -(when the volume is not mounted). If recollindex finds that one of -the topdirs is empty when starting up, any existing data for the -tree will be preserved by the indexing pass (no purge for this area).

-
-
-

Self contained volumes

-

As of RCL 1.24, it has become easy to build self-contained datasets -including a RCL configuration directory and index together with the -indexed documents, and to move such a dataset around (for example -copying it to an USB drive), without having to adjust the configuration -for querying the index.

-
-

Note

-

This is a query-time feature only. The index must only be updated in -its original location. If an update is necessary in a different -location, the index must be reset.

-
-

To make a long story short, here follows a script to create a RCL -configuration and index under a given directory (given as single -parameter). The resulting data set (files + recoll directory) can later -to be moved to a CDROM or thumb drive. Longer explanations come after -the script.

-
#!/bin/sh
-
-fatal()
-{
-    echo $*;exit 1
-}
-usage()
-{
-    fatal "Usage: init-recoll-volume.sh <top-directory>"
-}
-
-test $# = 1 || usage
-topdir=$1
-test -d "$topdir" || fatal $topdir should be a directory
-
-confdir="$topdir/recoll-config"
-test ! -d "$confdir" || fatal $confdir should not exist
-
-mkdir "$confdir"
-cd "$topdir"
-topdir=`pwd`
-cd "$confdir"
-confdir=`pwd`
-
-(echo topdirs = '"'$topdir'"'; \
- echo orgidxconfdir = $topdir/recoll-config) > "$confdir/recoll.conf"
-
-recollindex -c "$confdir"
-
-
-

The examples below will assume that you have a dataset under -/home/me/mydata/, with the index configuration and data stored -inside /home/me/mydata/recoll-confdir.

-

In order to be able to run queries after the dataset has been moved, you -must ensure the following:

-
    -
  • The main configuration file must define the -orgidxconfdir -variable to be the original location of the configuration directory -(orgidxconfdir=/home/me/mydata/recoll-confdir must be set inside -/home/me/mydata/recoll-confdir/recoll.conf in the example above).
  • -
  • The configuration directory must exist with the documents, somewhere -under the directory which will be moved. E.g. if you are moving -/home/me/mydata around, the configuration directory must exist -somewhere below this point, for example -/home/me/mydata/recoll-confdir, or -/home/me/mydata/sub/recoll-confdir.
  • -
  • You should keep the default locations for the index elements (they -are relative to the configuration directory by default). Only the -paths referring to the documents themselves (e.g. topdirs values) -should be absolute (in general, they are only used when indexing -anyway).
  • -
-

Only the first point needs an explicit user action, the RCL defaults are -compatible with the second one, and the third is natural.

-

If, after the move, the configuration directory needs to be copied out -of the dataset (for example because the thumb drive is too slow), you -can set the -curidxconfdir, -variable inside the copied configuration to define the location of the -moved one. For example if /home/me/mydata is now mounted onto -/media/me/somelabel, but the configuration directory and index has -been copied to /tmp/tempconfig, you would set curidxconfdir to -/media/me/somelabel/recoll-confdir inside -/tmp/tempconfig/recoll.conf. orgidxconfdir would still be -/home/me/mydata/recoll-confdir in the original and the copy.

-

If you are regularly copying the configuration out of the dataset, it -will be useful to write a script to automate the procedure. This can’t -really be done inside RCL because there are probably many possible -variants. One example would be to copy the configuration to make it -writable, but keep the index data on the medium because it is too big - -in this case, the script would also need to set dbdir in the copied -configuration.

-

The same set of modifications (RCL 1.24) has also made it possible to -run queries from a readonly configuration directory (with slightly -reduced function of course, such as not recording the query history).

-
-
-
-

Programming interface

-

RCL has an Application Programming Interface, usable both for indexing -and searching, currently accessible from the Python language.

-

Another less radical way to extend the application is to write input -handlers for new types of documents.

-

The processing of metadata attributes for documents (fields) is -highly configurable.

-
-

Writing a document input handler

-
-

Note

-

The small programs or pieces of code which handle the processing of -the different document types for RCL used to be called filters, -which is still reflected in the name of the directory which holds -them and many configuration variables. They were named this way -because one of their primary functions is to filter out the -formatting directives and keep the text content. However these -modules may have other behaviours, and the term input handler is -now progressively substituted in the documentation. filter is -still used in many places though.

-
-

RCL input handlers cooperate to translate from the multitude of input -document formats, simple ones as opendocument, acrobat, or compound ones -such as Zip or Email, into the final RCL indexing input format, which is -plain text (in many cases the processing pipeline has an intermediary -HTML step, which may be used for better previewing presentation). Most -input handlers are executable programs or scripts. A few handlers are -coded in C++ and live inside recollindex. This latter kind will not -be described here.

-

There are currently (since version 1.13) two kinds of external -executable input handlers:

-
    -
  • Simple exec handlers run once and exit. They can be bare programs -like antiword, or scripts using other programs. They are very -simple to write, because they just need to print the converted -document to the standard output. Their output can be plain text or -HTML. HTML is usually preferred because it can store metadata fields -and it allows preserving some of the formatting for the GUI preview. -However, these handlers have limitations:
      -
    • They can only process one document per file.
    • -
    • The output MIME type must be known and fixed.
    • -
    • The character encoding, if relevant, must be known and fixed (or -possibly just depending on location).
    • -
    -
  • -
  • Multiple execm handlers can process multiple files (sparing the -process startup time which can be very significant), or multiple -documents per file (e.g.: for archives or multi-chapter -publications). They communicate with the indexer through a simple -protocol, but are nevertheless a bit more complicated than the older -kind. Most of the new handlers are written in Python (exception: -rclimg which is written in Perl because exiftool has no real -Python equivalent). The Python handlers use common modules to factor -out the boilerplate, which can make them very simple in favorable -cases. The subdocuments output by these handlers can be directly -indexable (text or HTML), or they can be other simple or compound -documents that will need to be processed by another handler.
  • -
-

In both cases, handlers deal with regular file system files, and can -process either a single document, or a linear list of documents in each -file. RCL is responsible for performing up to date checks, deal with -more complex embedding and other upper level issues.

-

A simple handler returning a document in text/plain format, can -transfer no metadata to the indexer. Generic metadata, like document -size or modification date, will be gathered and stored by the indexer.

-

Handlers that produce text/html format can return an arbitrary -amount of metadata inside HTML meta tags. These will be processed -according to the directives found in the `fields configuration -file <#RCL.PROGRAM.FIELDS>`__.

-

The handlers that can handle multiple documents per file return a single -piece of data to identify each document inside the file. This piece of -data, called an ipath will be sent back by RCL to extract the -document at query time, for previewing, or for creating a temporary file -to be opened by a viewer. These handlers can also return metadata either -as HTML meta tags, or as named data through the communication -protocol.

-

The following section describes the simple handlers, and the next one -gives a few explanations about the execm ones. You could conceivably -write a simple handler with only the elements in the manual. This will -not be the case for the other ones, for which you will have to look at -the code.

-
-

Simple input handlers

-

RCL simple handlers are usually shell-scripts, but this is in no way -necessary. Extracting the text from the native format is the difficult -part. Outputting the format expected by RCL is trivial. Happily enough, -most document formats have translators or text extractors which can be -called from the handler. In some cases the output of the translating -program is completely appropriate, and no intermediate shell-script is -needed.

-

Input handlers are called with a single argument which is the source -file name. They should output the result to stdout.

-

When writing a handler, you should decide if it will output plain text -or HTML. Plain text is simpler, but you will not be able to add metadata -or vary the output character encoding (this will be defined in a -configuration file). Additionally, some formatting may be easier to -preserve when previewing HTML. Actually the deciding factor is metadata: -RCL has a way to extract metadata from the HTML header and use it for -field searches..

-

The RECOLL_FILTER_FORPREVIEW environment variable (values yes, -no) tells the handler if the operation is for indexing or -previewing. Some handlers use this to output a slightly different -format, for example stripping uninteresting repeated keywords (ie: -Subject: for email) when indexing. This is not essential.

-

You should look at one of the simple handlers, for example rclps for -a starting point.

-

Don’t forget to make your handler executable before testing !

-
-
-

“Multiple” handlers

-

If you can program and want to write an execm handler, it should not -be too difficult to make sense of one of the existing handlers.

-

The existing handlers differ in the amount of helper code which they are -using:

-
    -
  • rclimg is written in Perl and handles the execm protocol all by -itself (showing how trivial it is).
  • -
  • All the Python handlers share at least the rclexecm.py module, -which handles the communication. Have a look at, for example, -rclzip for a handler which uses rclexecm.py directly.
  • -
  • Most Python handlers which process single-document files by executing -another command are further abstracted by using the rclexec1.py -module. See for example rclrtf.py for a simple one, or -rcldoc.py for a slightly more complicated one (possibly executing -several commands).
  • -
  • Handlers which extract text from an XML document by using an XSLT -style sheet are now executed inside recollindex, with only the -style sheet stored in the filters/ directory. These can use a -single style sheet (e.g. abiword.xsl), or two sheets for the data -and metadata (e.g. opendoc-body.xsl and opendoc-meta.xsl). -The mimeconf configuration file defines how the sheets are used, -have a look. Before the C++ import, the xsl-based handlers used a -common module rclgenxslt.py, it is still around but unused. The -handler for OpenXML presentations is still the Python version because -the format did not fit with what the C++ code does. It would be a -good base for another similar issue.
  • -
-

There is a sample trivial handler based on rclexecm.py, with many -comments, not actually used by RCL. It would index a text file as one -document per line. Look for rcltxtlines.py in the src/filters -directory in the online RCL Git -repository (the sample not -in the distributed release at the moment).

-

You can also have a look at the slightly more complex rclzip which -uses Zip file paths as identifiers (ipath).

-

execm handlers sometimes need to make a choice for the nature of the -ipath elements that they use in communication with the indexer. Here -are a few guidelines:

-
    -
  • Use ASCII or UTF-8 (if the identifier is an integer print it, for -example, like printf %d would do).
  • -
  • If at all possible, the data should make some kind of sense when -printed to a log file to help with debugging.
  • -
  • RCL uses a colon (:) as a separator to store a complex path -internally (for deeper embedding). Colons inside the ipath -elements output by a handler will be escaped, but would be a bad -choice as a handler-specific separator (mostly, again, for debugging -issues).
  • -
-

In any case, the main goal is that it should be easy for the handler to -extract the target document, given the file name and the ipath -element.

-

execm handlers will also produce a document with a null ipath -element. Depending on the type of document, this may have some -associated data (e.g. the body of an email message), or none (typical -for an archive file). If it is empty, this document will be useful -anyway for some operations, as the parent of the actual data documents.

-
-
-

Telling RCL about the handler

-

There are two elements that link a file to the handler which should -process it: the association of file to MIME type and the association of -a MIME type with a handler.

-

The association of files to MIME types is mostly based on name suffixes. -The types are defined inside the `mimemap -file <#RCL.INSTALL.CONFIG.MIMEMAP>`__. Example:

-
.doc = application/msword
-
-
-

If no suffix association is found for the file name, RCL will try to -execute a system command (typically file -i or xdg-mime) to -determine a MIME type.

-

The second element is the association of MIME types to handlers in the -`mimeconf file <#RCL.INSTALL.CONFIG.MIMECONF>`__. A sample will -probably be better than a long explanation:

-
[index]
-application/msword = exec antiword -t -i 1 -m UTF-8;\
-mimetype = text/plain ; charset=utf-8
-
-application/ogg = exec rclogg
-
-text/rtf = exec unrtf --nopict --html; charset=iso-8859-1; mimetype=text/html
-
-application/x-chm = execm rclchm
-
-
-

The fragment specifies that:

-
    -
  • application/msword files are processed by executing the -antiword program, which outputs text/plain encoded in -utf-8.
  • -
  • application/ogg files are processed by the rclogg script, -with default output type (text/html, with encoding specified in -the header, or utf-8 by default).
  • -
  • text/rtf is processed by unrtf, which outputs text/html. -The iso-8859-1 encoding is specified because it is not the -utf-8 default, and not output by unrtf in the HTML header -section.
  • -
  • application/x-chm is processed by a persistant handler. This is -determined by the execm keyword.
  • -
-
-
-

Input handler output

-

Both the simple and persistent input handlers can return any MIME type -to Recoll, which will further process the data according to the MIME -configuration.

-

Most input filters filters produce either text/plain or -text/html data. There are exceptions, for example, filters which -process archive file (zip, tar, etc.) will usually return the -documents as they are found, without processing them further.

-

There is nothing to say about text/plain output, except that its -character encoding should be consistent with what is specified in the -mimeconf file.

-

For filters producing HTML, the output could be very minimal like the -following example:

-
<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
-</head>
-<body>
-Some text content
-</body>
-</html>
-
-
-

You should take care to escape some characters inside the text by -transforming them into appropriate entities. At the very minimum, -“&” should be transformed into “&amp;”, “<” should be -transformed into “&lt;”. This is not always properly done by -external helper programs which output HTML, and of course never by those -which output plain text.

-

When encapsulating plain text in an HTML body, the display of a preview -may be improved by enclosing the text inside <pre> tags.

-

The character set needs to be specified in the header. It does not need -to be UTF-8 (RCL will take care of translating it), but it must be -accurate for good results.

-

RCL will process meta tags inside the header as possible document -fields candidates. Documents fields can be processed by the indexer in -different ways, for searching or displaying inside query results. This -is described in a following section.

-

By default, the indexer will process the standard header fields if they -are present: title, meta/description, and meta/keywords are -both indexed and stored for query-time display.

-

A predefined non-standard meta tag will also be processed by RCL -without further configuration: if a date tag is present and has the -right format, it will be used as the document date (for display and -sorting), in preference to the file modification date. The date format -should be as follows:

-
<meta name="date" content="YYYY-mm-dd HH:MM:SS">
-or
-<meta name="date" content="YYYY-mm-ddTHH:MM:SS">
-
-
-

Example:

-
<meta name="date" content="2013-02-24 17:50:00">
-
-
-

Input handlers also have the possibility to “invent” field names. This -should also be output as meta tags:

-
<meta name="somefield" content="Some textual data" />
-
-
-

You can embed HTML markup inside the content of custom fields, for -improving the display inside result lists. In this case, add a (wildly -non-standard) markup attribute to tell RCL that the value is HTML -and should not be escaped for display.

-
<meta name="somefield" markup="html" content="Some <i>textual</i> data" />
-
-
-

As written above, the processing of fields is described in a further -section.

-

Persistent filters can use another, probably simpler, method to produce -metadata, by calling the setfield() helper method. This avoids the -necessity to produce HTML, and any issue with HTML quoting. See, for -example, rclaudio in RCL 1.23 and later for an example of handler -which outputs text/plain and uses setfield() to produce -metadata.

-
-
-

Page numbers

-

The indexer will interpret ^L characters in the handler output as -indicating page breaks, and will record them. At query time, this allows -starting a viewer on the right page for a hit or a snippet. Currently, -only the PDF, Postscript and DVI handlers generate page breaks.

-
-
-
-

Field data processing

-

Fields are named pieces of information in or about documents, like -title, author, abstract.

-

The field values for documents can appear in several ways during -indexing: either output by input handlers as meta fields in the HTML -header section, or extracted from file extended attributes, or added as -attributes of the Doc object when using the API, or again -synthetized internally by RCL.

-

The RCL query language allows searching for text in a specific field.

-

RCL defines a number of default fields. Additional ones can be output by -handlers, and described in the fields configuration file.

-

Fields can be:

-
    -
  • indexed, meaning that their terms are separately stored in -inverted lists (with a specific prefix), and that a field-specific -search is possible.
  • -
  • stored, meaning that their value is recorded in the index data -record for the document, and can be returned and displayed with -search results.
  • -
-

A field can be either or both indexed and stored. This and other aspects -of fields handling is defined inside the fields configuration file.

-

Some fields may also designated as supporting range queries, meaning -that the results may be selected for an interval of its values. See the -configuration section for more details.

-

The sequence of events for field processing is as follows:

-
    -
  • During indexing, recollindex scans all meta fields in HTML -documents (most document types are transformed into HTML at some -point). It compares the name for each element to the configuration -defining what should be done with fields (the fields file)
  • -
  • If the name for the meta element matches one for a field that -should be indexed, the contents are processed and the terms are -entered into the index with the prefix defined in the fields -file.
  • -
  • If the name for the meta element matches one for a field that -should be stored, the content of the element is stored with the -document data record, from which it can be extracted and displayed at -query time.
  • -
  • At query time, if a field search is performed, the index prefix is -computed and the match is only performed against appropriately -prefixed terms in the index.
  • -
  • At query time, the field can be displayed inside the result list by -using the appropriate directive in the definition of the result list -paragraph format. All fields are -displayed on the fields screen of the preview window (which you can -reach through the right-click menu). This is independant of the fact -that the search which produced the results used the field or not.
  • -
-

You can find more information in the section about the ``fields` -file <#RCL.INSTALL.CONFIG.FIELDS>`__, or in comments inside the file.

-

You can also have a look at the example in the FAQs -area, detailing how one could add a page -count field to pdf documents for displaying inside result lists.

-
-
-

Python API

-
-

Introduction

-

The RCL Python programming interface can be used both for searching and -for creating/updating an index. Bindings exist for Python2 and Python3.

-

The search interface is used in a number of active projects: the RCL -Gnome Shell Search Provider, the RCL Web UI, and the upmpdcli UPnP Media -Server, in addition to many small scripts.

-

The index update section of the API may be used to create and update RCL -indexes on specific configurations (separate from the ones created by -recollindex). The resulting databases can be queried alone, or in -conjunction with regular ones, through the GUI or any of the query -interfaces.

-

The search API is modeled along the Python database API specification. -There were two major changes along RCL versions:

-
    -
  • The basis for the RCL API changed from Python database API version -1.0 (RCL versions up to 1.18.1), to version 2.0 (RCL 1.18.2 and -later).
  • -
  • The recoll module became a package (with an internal recoll -module) as of RCL version 1.19, in order to add more functions. For -existing code, this only changes the way the interface must be -imported.
  • -
-

We will describe the new API and package structure here. A paragraph at -the end of this section will explain a few differences and ways to write -code compatible with both versions.

-

The recoll package now contains two modules:

-
    -
  • The recoll module contains functions and classes used to query -(or update) the index.
  • -
  • The rclextract module contains functions and classes used at -query time to access document data.
  • -
-

There is a good chance that your system repository has packages for the -Recoll Python API, sometimes in a package separate from the main one -(maybe named something like python-recoll). Else refer to the Building -from source chapter.

-

As an introduction, the following small sample will run a query and list -the title and url for each of the results. It would work with RCL 1.19 -and later. The python/samples source directory contains several -examples of Python programming with RCL, exercising the extension more -completely, and especially its data extraction features.

-
#!/usr/bin/env python
-
-from recoll import recoll
-
-db = recoll.connect()
-query = db.query()
-nres = query.execute("some query")
-results = query.fetchmany(20)
-for doc in results:
-    print("%s %s" % (doc.url, doc.title))
-
-
-

You can also take a look at the source for the Recoll -WebUI, -the upmpdcli local media -server, -or the Gnome Shell Search -Provider.

-
-
-

Interface elements

-

A few elements in the interface are specific and and need an -explanation.

-
-
ipath
-
This data value (set as a field in the Doc object) is stored, along -with the URL, but not indexed by RCL. Its contents are not -interpreted by the index layer, and its use is up to the -application. For example, the RCL file system indexer uses the -ipath to store the part of the document access path internal to -(possibly imbricated) container documents. ipath in this case is -a vector of access elements (e.g, the first part could be a path -inside a zip file to an archive member which happens to be an mbox -file, the second element would be the message sequential number -inside the mbox etc.). url and ipath are returned in every -search result and define the access to the original document. -ipath is empty for top-level document/files (e.g. a PDF document -which is a filesystem file). The RCL GUI knows about the structure -of the ipath values used by the filesystem indexer, and uses it -for such functions as opening the parent of a given document.
-
udi
-
An udi (unique document identifier) identifies a document. -Because of limitations inside the index engine, it is restricted in -length (to 200 bytes), which is why a regular URI cannot be used. -The structure and contents of the udi is defined by the -application and opaque to the index engine. For example, the -internal file system indexer uses the complete document path (file -path + internal path), truncated to length, the suppressed part -being replaced by a hash value. The udi is not explicit in the -query interface (it is used “under the hood” by the rclextract -module), but it is an explicit element of the update interface.
-
parent_udi
-
If this attribute is set on a document when entering it in the -index, it designates its physical container document. In a -multilevel hierarchy, this may not be the immediate parent. -parent_udi is optional, but its use by an indexer may simplify -index maintenance, as RCL will automatically delete all children -defined by parent_udi == udi when the document designated by -udi is destroyed. e.g. if a Zip archive contains entries -which are themselves containers, like mbox files, all the -subdocuments inside the Zip file (mbox, messages, message -attachments, etc.) would have the same parent_udi, matching the -udi for the Zip file, and all would be destroyed when the -Zip file (identified by its udi) is removed from the index. -The standard filesystem indexer uses parent_udi.
-
Stored and indexed fields
-
The `fields file <#RCL.INSTALL.CONFIG.FIELDS>`__ inside the RCL -configuration defines which document fields are either indexed -(searchable), stored (retrievable with search results), or both. -Apart from a few standard/internal fields, only the stored -fields are retrievable through the Python search interface.
-
-
-
-

Python search interface

-
-
The recoll module
-

The connect() function connects to one or several RCL index(es) and -returns a Db object.

-

This call initializes the recoll module, and it should always be -performed before any other call or object creation.

-
    -
  • confdir may specify a configuration directory. The usual defaults -apply.
  • -
  • extra_dbs is a list of additional indexes (Xapian directories).
  • -
  • writable decides if we can index new data through this -connection.
  • -
-

A Db object is created by a connect() call and holds a connection to -a Recoll index.

-
-
Db.close()
-
Closes the connection. You can’t do anything with the Db object -after this.
-
Db.query(), Db.cursor()
-
These aliases return a blank Query object for this index.
-
Db.setAbstractParams(maxchars, contextwords)
-
Set the parameters used to build snippets (sets of keywords in -context text fragments). maxchars defines the maximum total size -of the abstract. contextwords defines how many terms are shown -around the keyword.
-
-

Db.termMatch(match_type, expr, field=’‘, maxlen=-1, casesens=False, -diacsens=False, lang=’english’)

-
-
Expand an expression against the index term list. Performs the basic -function from the GUI term explorer tool. match_type can be -either of wildcard, regexp or stem. Returns a list of -terms expanded from the input expression.
-

A Query object (equivalent to a cursor in the Python DB API) is -created by a Db.query() call. It is used to execute index searches.

-
-
Query.sortby(fieldname, ascending=True)
-
Sort results by fieldname, in ascending or descending order. Must be -called before executing the search.
-
-

Query.execute(query_string, stemming=1, stemlang=”english”, -fetchtext=False)

-
-
Starts a search for query_string, a RCL search language string. If -the index stores the document texts and fetchtext is True, store -the document extracted text in doc.text.
-
-
Query.executesd(SearchData, fetchtext=False)
-
Starts a search for the query defined by the SearchData object. If -the index stores the document texts and fetchtext is True, store -the document extracted text in doc.text.
-
Query.fetchmany(size=query.arraysize)
-
Fetches the next Doc objects in the current search results, and -returns them as an array of the required size, which is by default -the value of the arraysize data member.
-
Query.fetchone()
-
Fetches the next Doc object from the current search results. -Generates a StopIteration exception if there are no results left.
-
Query.close()
-
Closes the query. The object is unusable after the call.
-
Query.scroll(value, mode=’relative’)
-
Adjusts the position in the current result set. mode can be -relative or absolute.
-
Query.getgroups()
-
Retrieves the expanded query terms as a list of pairs. Meaningful -only after executexx In each pair, the first entry is a list of user -terms (of size one for simple terms, or more for group and phrase -clauses), the second a list of query terms as derived from the user -terms and used in the Xapian Query.
-
Query.getxquery()
-
Return the Xapian query description as a Unicode string. Meaningful -only after executexx.
-
Query.highlight(text, ishtml = 0, methods = object)
-
Will insert <span “class=rclmatch”>, </span> tags around the match -areas in the input text and return the modified text. ishtml can -be set to indicate that the input text is HTML and that HTML special -characters should not be escaped. methods if set should be an -object with methods startMatch(i) and endMatch() which will be -called for each match and should return a begin and end tag
-
Query.makedocabstract(doc, methods = object))
-
Create a snippets abstract for doc (a Doc object) by -selecting text around the match terms. If methods is set, will also -perform highlighting. See the highlight method.
-
Query.__iter__() and Query.next()
-
-
So that things like ``for doc in
-
query:`` will work.
-
-
-
Query.arraysize
-
Default number of records processed by fetchmany (r/w).
-
Query.rowcount
-
Number of records returned by the last execute.
-
Query.rownumber
-
Next index to be fetched from results. Normally increments after -each fetchone() call, but can be set/reset before the call to effect -seeking (equivalent to using scroll()). Starts at 0.
-
-

A Doc object contains index data for a given document. The data is -extracted from the index when searching, or set by the indexer program -when updating. The Doc object has many attributes to be read or set by -its user. It mostly matches the Rcl::Doc C++ object. Some of the -attributes are predefined, but, especially when indexing, others can be -set, the name of which will be processed as field names by the indexing -configuration. Inputs can be specified as Unicode or strings. Outputs -are Unicode objects. All dates are specified as Unix timestamps, printed -as strings. Please refer to the rcldb/rcldoc.cpp C++ file for a full -description of the predefined attributes. Here follows a short list.

-
    -
  • url the document URL but see also getbinurl()
  • -
  • ipath the document ipath for embedded documents.
  • -
  • fbytes, dbytes the document file and text sizes.
  • -
  • fmtime, dmtime the document file and document times.
  • -
  • xdocid the document Xapian document ID. This is useful if you -want to access the document through a direct Xapian operation.
  • -
  • mtype the document MIME type.
  • -
  • Fields stored by default: author, filename, keywords, -recipient
  • -
-

At query time, only the fields that are defined as stored either by -default or in the fields configuration file will be meaningful in -the Doc object. The document processed text may be present or not, -depending if the index stores the text at all, and if it does, on the -fetchtext query execute option. See also the rclextract module -for accessing document contents.

-
-
get(key), [] operator
-

Retrieve the named document attribute. You can also use -``getattr(doc,

-
-
key)`` or doc.key.
-
-
doc.key = value
-

Set the the named document attribute. You can also use -``setattr(doc, key,

-
-
value)``.
-
-
getbinurl()
-
Retrieve the URL in byte array format (no transcoding), for use as -parameter to a system call.
-
setbinurl(url)
-
Set the URL in byte array format (no transcoding).
-
items()
-
Return a dictionary of doc object keys/values
-
keys()
-
list of doc object keys (attribute names).
-
-

A SearchData object allows building a query by combining clauses, -for execution by Query.executesd(). It can be used in replacement of -the query language approach. The interface is going to change a little, -so no detailed doc for now...

-

addclause(type=’and’|’or’|’excl’|’phrase’|’near’|’sub’, -qstring=string, slack=0, field=’‘, stemming=1, subSearch=SearchData)

-
-
-
The rclextract module
-

Prior to RCL 1.25, index queries could not provide document content -because it was never stored. RCL 1.25 and later usually store the -document text, which can be optionally retrieved when running a query -(see query.execute() above - the result is always plain text).

-

The rclextract module can give access to the original document and -to the document text content (if not stored by the index, or to access -an HTML version of the text). Acessing the original document is -particularly useful if it is embedded (e.g. an email attachment).

-

You need to import the recoll module before the rclextract -module.

-
-
Extractor(doc)
-
An Extractor object is built from a Doc object, output from -a query.
-
Extractor.textextract(ipath)
-

Extract document defined by ipath and return a Doc object. The -doc.text field has the document text converted to either -text/plain or text/html according to doc.mimetype. The typical -use would be as follows:

-
from recoll import recoll, rclextract
-
-qdoc = query.fetchone()
-extractor = recoll.Extractor(qdoc)
-doc = extractor.textextract(qdoc.ipath)
-# use doc.text, e.g. for previewing
-
-
-

Passing qdoc.ipath to textextract() is redundant, but -reflects the fact that the Extractor object actually has the -capability to access the other entries in a compound document.

-
-
Extractor.idoctofile(ipath, targetmtype, outfile=’‘)
-

Extracts document into an output file, which can be given explicitly -or will be created as a temporary file to be deleted by the caller. -Typical use:

-
from recoll import recoll, rclextract
-
-qdoc = query.fetchone()
-extractor = recoll.Extractor(qdoc)
-filename = extractor.idoctofile(qdoc.ipath, qdoc.mimetype)
-
-
-

In all cases the output is a copy, even if the requested document is -a regular system file, which may be wasteful in some cases. If you -want to avoid this, you can test for a simple file document as -follows:

-
not doc.ipath and (not "rclbes" in doc.keys() or doc["rclbes"] == "FS")
-
-
-
-
-
-
-
Search API usage example
-

The following sample would query the index with a user language string. -See the python/samples directory inside the RCL source for other -examples. The recollgui subdirectory has a very embryonic GUI which -demonstrates the highlighting and data extraction functions.

-
#!/usr/bin/env python
-
-from recoll import recoll
-
-db = recoll.connect()
-db.setAbstractParams(maxchars=80, contextwords=4)
-
-query = db.query()
-nres = query.execute("some user question")
-print "Result count: ", nres
-if nres > 5:
-    nres = 5
-for i in range(nres):
-    doc = query.fetchone()
-    print "Result #%d" % (query.rownumber,)
-    for k in ("title", "size"):
-        print k, ":", getattr(doc, k).encode('utf-8')
-    abs = db.makeDocAbstract(doc, query).encode('utf-8')
-    print abs
-    print
-
-
-
-
-
-

Creating Python external indexers

-

The update API can be used to create an index from data which is not -accessible to the regular RCL indexer, or structured to present -difficulties to the RCL input handlers.

-

An indexer created using this API will be have equivalent work to do as -the the Recoll file system indexer: look for modified documents, extract -their text, call the API for indexing it, take care of purging the index -out of data from documents which do not exist in the document store any -more.

-

The data for such an external indexer should be stored in an index -separate from any used by the RCL internal file system indexer. The -reason is that the main document indexer purge pass (removal of deleted -documents) would also remove all the documents belonging to the external -indexer, as they were not seen during the filesystem walk. The main -indexer documents would also probably be a problem for the external -indexer own purge operation.

-

While there would be ways to enable multiple foreign indexers to -cooperate on a single index, it is just simpler to use separate ones, -and use the multiple index access capabilities of the query interface, -if needed.

-

There are two parts in the update interface:

-
    -
  • Methods inside the recoll module allow inserting data into the -index, to make it accessible by the normal query interface.
  • -
  • An interface based on scripts execution is defined to allow either -the GUI or the rclextract module to access original document data -for previewing or editing.
  • -
-
-
Python update interface
-

The update methods are part of the recoll module described above. -The connect() method is used with a writable=true parameter to -obtain a writable Db object. The following Db object methods are -then available.

-
-
addOrUpdate(udi, doc, parent_udi=None)
-

Add or update index data for a given document The ``

-
-
udi`` string must define a unique id for the
-

document. It is an opaque interface element and not interpreted -inside Recoll. doc is a ``

-
-
Doc`` object, created from the data to be
-

indexed (the main text should be in doc.text). If ``

-
-
parent_udi`` is set, this is a unique
-

identifier for the top-level container (e.g. for the filesystem -indexer, this would be the one which is an actual file).

-
-
delete(udi)
-
Purge index from all data for udi, and all documents (if any) -which have a matrching parent_udi.
-
needUpdate(udi, sig)
-

Test if the index needs to be updated for the document identified by -udi. If this call is to be used, the doc.sig field should -contain a signature value when calling addOrUpdate(). The -needUpdate() call then compares its parameter value with the -stored sig for udi. sig is an opaque value, compared as -a string.

-

The filesystem indexer uses a concatenation of the decimal string -values for file size and update time, but a hash of the contents -could also be used.

-

As a side effect, if the return value is false (the index is up to -date), the call will set the existence flag for the document (and -any subdocument defined by its parent_udi), so that a later -purge() call will preserve them).

-

The use of needUpdate() and purge() is optional, and the -indexer may use another method for checking the need to reindex or -to delete stale entries.

-
-
purge()
-
Delete all documents that were not touched during the just finished -indexing pass (since open-for-write). These are the documents for -the needUpdate() call was not performed, indicating that they no -longer exist in the primary storage system.
-
-
-
-
Query data access for external indexers (1.23)
-

RCL has internal methods to access document data for its internal -(filesystem) indexer. An external indexer needs to provide data access -methods if it needs integration with the GUI (e.g. preview function), or -support for the rclextract module.

-

The index data and the access method are linked by the rclbes -(recoll backend storage) Doc field. You should set this to a short -string value identifying your indexer (e.g. the filesystem indexer uses -either “FS” or an empty value, the Web history indexer uses “BGL”).

-

The link is actually performed inside a backends configuration file -(stored in the configuration directory). This defines commands to -execute to access data from the specified indexer. Example, for the mbox -indexing sample found in the Recoll source (which sets -rclbes="MBOX"):

-
[MBOX]
-          fetch = /path/to/recoll/src/python/samples/rclmbox.py fetch
-          makesig = path/to/recoll/src/python/samples/rclmbox.py makesig
-
-
-

fetch and makesig define two commands to execute to respectively -retrieve the document text and compute the document signature (the -example implementation uses the same script with different first -parameters to perform both operations).

-

The scripts are called with three additional arguments: udi, -url, ipath, stored with the document when it was indexed, and -may use any or all to perform the requested operation. The caller -expects the result data on stdout.

-
-
-
External indexer samples
-

The Recoll source tree has two samples of external indexers in the -src/python/samples directory. The more interesting one is -rclmbox.py which indexes a directory containing mbox folder -files. It exercises most features in the update interface, and has a -data access interface.

-

See the comments inside the file for more information.

-
-
-
-

Package compatibility with the previous version

-

The following code fragments can be used to ensure that code can run -with both the old and the new API (as long as it does not use the new -abilities of the new API of course).

-

Adapting to the new package structure:

-
try:
-from recoll import recoll
-from recoll import rclextract
-hasextract = True
-except:
-import recoll
-hasextract = False
-
-
-

Adapting to the change of nature of the next Query member. The -same test can be used to choose to use the scroll() method (new) or -set the next value (old).

-
rownum = query.next if type(query.next) == int else \
-query.rownumber
-
-
-
-
-
-
-

Installation and configuration

-
-

Installing a binary copy

-

RCL binary copies are always distributed as regular packages for your -system. They can be obtained either through the system’s normal software -distribution framework (e.g. Debian/Ubuntu apt, FreeBSD ports, etc.), or -from some type of “backports” repository providing versions newer than -the standard ones, or found on the RCL WEB site in some cases. The most -up-to-date information about Recoll packages can usually be found on the -Recoll WEB site downloads page

-

There used to exist another form of binary install, as pre-compiled -source trees, but these are just less convenient than the packages and -don’t exist any more.

-

The package management tools will usually automatically deal with hard -dependancies for packages obtained from a proper package repository. You -will have to deal with them by hand for downloaded packages (for -example, when dpkg complains about missing dependancies).

-

In all cases, you will have to check or install supporting -applications for the file types that you want -to index beyond those that are natively processed by RCL (text, HTML, -email files, and a few others).

-

You should also maybe have a look at the configuration -section (but this may not be necessary for a -quick test with default parameters). Most parameters can be more -conveniently set from the GUI interface.

-
-
-

Supporting packages

-
-

Note

-

The WIN installation of RCL is self-contained, and only needs Python -2.7 to be externally installed. WIN users can skip this section.

-
-

RCL uses external applications to index some file types. You need to -install them for the file types that you wish to have indexed (these are -run-time optional dependencies. None is needed for building or running -RCL except for indexing their specific file type).

-

After an indexing pass, the commands that were found missing can be -displayed from the recoll File menu. The list is stored in the -missing text file inside the configuration directory.

-

A list of common file types which need external commands follows. Many -of the handlers need the iconv command, which is not always listed -as a dependancy.

-

Please note that, due to the relatively dynamic nature of this -information, the most up to date version is now kept on RCLAPPS along -with links to the home pages or best source/patches pages, and misc -tips. The list below is not updated often and may be quite stale.

-

For many Linux distributions, most of the commands listed can be -installed from the package repositories. However, the packages are -sometimes outdated, or not the best version for RCL, so you should take -a look at RCLAPPS if a file type is important to you.

-

As of RCL release 1.14, a number of XML-based formats that were handled -by ad hoc handler code now use the xsltproc command, which usually -comes with libxslt. These are: abiword, fb2 (ebooks), kword, openoffice, -svg.

-

Now for the list:

-
    -
  • Openoffice files need unzip and xsltproc.
  • -
  • PDF files need pdftotext which is part of Poppler (usually comes -with the poppler-utils package). Avoid the original one from -Xpdf.
  • -
  • Postscript files need pstotext. The original version has an issue -with shell character in file names, which is corrected in recent -packages. See RCLAPPS for more detail.
  • -
  • MS Word needs antiword. It is also useful to have wvWare -installed as it may be be used as a fallback for some files which -antiword does not handle.
  • -
  • MS Excel and PowerPoint are processed by internal Python -handlers.
  • -
  • -
    MS Open XML (docx) needs ``
    -
    xsltproc``.
    -
    -
  • -
  • Wordperfect files need wpd2html from the libwpd (or libwpd-tools -on Ubuntu) package.
  • -
  • RTF files need unrtf, which, in its older versions, has much -trouble with non-western character sets. Many Linux distributions -carry outdated unrtf versions. Check RCLAPPS for details.
  • -
  • TeX files need untex or detex. Check RCLAPPS for sources if -it’s not packaged for your distribution.
  • -
  • dvi files need dvips.
  • -
  • djvu files need djvutxt and djvused from the DjVuLibre -package.
  • -
  • Audio files: RCL releases 1.14 and later use a single Python handler -based on mutagen for all audio file types.
  • -
  • Pictures: RCL uses the Exiftool Perl package to extract tag -information. Most image file formats are supported. Note that there -may not be much interest in indexing the technical tags (image size, -aperture, etc.). This is only of interest if you store personal tags -or textual descriptions inside the image files.
  • -
  • chm: files in Microsoft help format need Python and the pychm module -(which needs chmlib).
  • -
  • ICS: up to RCL 1.13, iCalendar files need Python and the icalendar -module. icalendar is not needed for newer versions, which use -internal code.
  • -
  • Zip archives need Python (and the standard zipfile module).
  • -
  • Rar archives need Python, the rarfile Python module and the unrar -utility.
  • -
  • Midi karaoke files need Python and the Midi -module
  • -
  • Konqueror webarchive format with Python (uses the Tarfile module).
  • -
  • Mimehtml web archive format (support based on the email handler, -which introduces some mild weirdness, but still usable).
  • -
-

Text, HTML, email folders, and Scribus files are processed internally. -Lyx is used to index Lyx files. Many handlers need iconv and the -standard sed and awk.

-
-
-

Building from source

-
-

Prerequisites

-

The following prerequisites are described in broad terms and not as -specific package names (which will depend on the exact platform). The -dependancies should be available as packages on most common Unix -derivatives, and it should be quite uncommon that you would have to -build one of them.

-

The shopping list:

-
    -
  • The autoconf, automake and libtool triad. Only -autoconf is needed for RCL 1.21 and earlier.

    -
  • -
  • C++ compiler. Recent versions require C++11 compatibility (1.23 and -later).

    -
  • -
  • bison command (for RCL 1.21 and later).

    -
  • -
  • xsltproc command. For building the documentation (for RCL 1.21 -and later). This sometimes comes with the libxslt package. And also -the Docbook XML and style sheet files.

    -
  • -
  • Development files for Xapian core.

    -
    -

    Important

    -

    If you are building Xapian for an older CPU (before Pentium 4 or -Athlon 64), you need to add the --disable-sse flag to the -configure command. Else all Xapian application will crash with an -illegal instruction error.

    -
    -
  • -
  • Development files for Qt 4 or Qt -5. RCL 1.15.9 was the last -version to support Qt 3. If you do not want to install or build the -Qt Webkit module, RCL has a configuration option to disable its use -(see further in the configuration section).

    -
  • -
  • Development files for X11 and zlib.

    -
  • -
  • Development files for Python (or use --disable-python-module).

    -
  • -
  • You may also need -libiconv. On Linux -systems, the iconv interface is part of libc and you should not need -to do anything special.

    -
  • -
-

Check the RCL download page -for up to date version information.

-
-
-

Building

-

RCL has been built on Linux, FreeBSD, Mac OS X, and Solaris, most -versions after 2005 should be ok, maybe some older ones too (Solaris 8 -is ok). If you build on another system, and need to modify things, I -would very much welcome patches.

-

Configure options:.

-
    -
  • --without-aspell will disable the code for phonetic matching of -search terms.

    -
  • -
  • --with-fam or --with-inotify will enable the code for real -time indexing. Inotify support is enabled by default on recent Linux -systems.

    -
  • -
  • --with-qzeitgeist will enable sending Zeitgeist events about the -visited search results, and needs the qzeitgeist package.

    -
  • -
  • --disable-webkit is available from version 1.17 to implement the -result list with a Qt QTextBrowser instead of a WebKit widget if you -do not or can’t depend on the latter.

    -
  • -
  • --disable-idxthreads is available from version 1.19 to suppress -multithreading inside the indexing process. You can also use the -run-time configuration to restrict recollindex to using a single -thread, but the compile-time option may disable a few more unused -locks. This only applies to the use of multithreading for the core -index processing (data input). The RCL monitor mode always uses at -least two threads of execution.

    -
  • -
  • --disable-python-module will avoid building the Python module.

    -
  • -
  • --disable-xattr will prevent fetching data from file extended -attributes. Beyond a few standard attributes, fetching extended -attributes data can only be useful is some application stores data in -there, and also needs some simple configuration (see comments in the -fields configuration file).

    -
  • -
  • --enable-camelcase will enable splitting camelCase words. This is -not enabled by default as it has the unfortunate side-effect of -making some phrase searches quite confusing: ie, "MySQL manual" -would be matched by "MySQL manual" and "my sql manual" but -not ``“mysql

    -
    -

    manual”`` (only inside phrase searches).

    -
    -
  • -
  • --with-file-command Specify the version of the ‘file’ command to -use (ie: –with-file-command=/usr/local/bin/file). Can be useful to -enable the gnu version on systems where the native one is bad.

    -
  • -
  • --disable-qtgui Disable the Qt interface. Will allow building the -indexer and the command line search program in absence of a Qt -environment.

    -
  • -
  • --disable-x11mon Disable X11 connection monitoring inside -recollindex. Together with –disable-qtgui, this allows building -recoll without Qt and X11.

    -
  • -
  • --disable-userdoc will avoid building the user manual. This -avoids having to install the Docbook XML/XSL files and the TeX -toolchain used for translating the manual to PDF.

    -
  • -
  • --disable-pic (RCL versions up to 1.21 only) will compile RCL -with position-dependant code. This is incompatible with building the -KIO or the Python or PHP extensions, but might yield very marginally -faster code.

    -
  • -
  • Of course the usual autoconf configure options, like --prefix -apply.

    -
  • -
-

Normal procedure (for source extracted from a tar distribution):

-
cd recoll-xxx
-./configure
-make
-(practices usual hardship-repelling invocations)
-
-
-

When building from source cloned from the git repository, you also need -to install autoconf, automake, and libtool and you must execute ``sh

-
-
autogen.sh`` in the top source directory before running
-

configure.

-
-
-

Installing

-

Use make install in the root of the source tree. This will copy the -commands to prefix/bin and the sample configuration files, scripts -and other shared data to prefix/share/recoll.

-
-
-

Python API package

-

The Python interface can be found in the source tree, under the -python/recoll directory.

-

As of RCL 1.19, the module can be compiled for Python3.

-

The normal RCL build procedure (see above) installs the API package for -the default system version (python) along with the main code. The -package for other Python versions (e.g. python3 if the system default is -python2) must be explicitely built and installed.

-

The python/recoll/ directory contains the usual setup.py. After -configuring and building the main RCL code, you can use the script to -build and install the Python module:

-
cd recoll-xxx/python/recoll
-pythonX setup.py build
-sudo pythonX setup.py install
-
-
-
-
-

Building on Solaris

-

We did not test building the GUI on Solaris for recent versions. You -will need at least Qt 4.4. There are some hints on an old web site -page, they may still be -valid.

-

Someone did test the 1.19 indexer and Python module build, they do work, -with a few minor glitches. Be sure to use GNU make and install.

-
-
-
-

Configuration overview

-

Most of the parameters specific to the recoll GUI are set through -the Preferences menu and stored in the standard Qt place -($HOME/.config/Recoll.org/recoll.conf). You probably do not want to -edit this by hand.

-

RCL indexing options are set inside text configuration files located in -a configuration directory. There can be several such directories, each -of which defines the parameters for one index.

-

The configuration files can be edited by hand or through the Index -configuration dialog (Preferences menu). The GUI tool will try to -respect your formatting and comments as much as possible, so it is quite -possible to use both approaches on the same configuration.

-

The most accurate documentation for the configuration parameters is -given by comments inside the default files, and we will just give a -general overview here.

-

For each index, there are at least two sets of configuration files. -System-wide configuration files are kept in a directory named like -/usr/share/recoll/examples, and define default values, shared by all -indexes. For each index, a parallel set of files defines the customized -parameters.

-

The default location of the customized configuration is the .recoll -directory in your home. Most people will only use this directory.

-

This location can be changed, or others can be added with the -RECOLL_CONFDIR environment variable or the -c option parameter to -recoll and recollindex.

-

In addition (as of RCL version 1.19.7), it is possible to specify two -additional configuration directories which will be stacked before and -after the user configuration directory. These are defined by the -RECOLL_CONFTOP and RECOLL_CONFMID environment variables. Values from -configuration files inside the top directory will override user ones, -values from configuration files inside the middle directory will -override system ones and be overriden by user ones. These two variables -may be of use to applications which augment RCL functionality, and need -to add configuration data without disturbing the user’s files. Please -note that the two, currently single, values will probably be interpreted -as colon-separated lists in the future: do not use colon characters -inside the directory paths.

-

If the .recoll directory does not exist when recoll or -recollindex are started, it will be created with a set of empty -configuration files. recoll will give you a chance to edit the -configuration file before starting indexing. recollindex will -proceed immediately. To avoid mistakes, the automatic directory creation -will only occur for the default location, not if -c or -RECOLL_CONFDIR were used (in the latter cases, you will have to create -the directory).

-

All configuration files share the same format. For example, a short -extract of the main configuration file might look as follows:

-
# Space-separated list of files and directories to index.
-topdirs =  ~/docs /usr/share/doc
-
-[~/somedirectory-with-utf8-txt-files]
-defaultcharset = utf-8
-
-
-

There are three kinds of lines:

-
    -
  • Comment (starts with #) or empty.
  • -
  • Parameter affectation (name = value).
  • -
  • Section definition ([somedirname]).
  • -
-

Long lines can be broken by ending each incomplete part with a backslash -(\).

-

Depending on the type of configuration file, section definitions either -separate groups of parameters or allow redefining some parameters for a -directory sub-tree. They stay in effect until another section -definition, or the end of file, is encountered. Some of the parameters -used for indexing are looked up hierarchically from the current -directory location upwards. Not all parameters can be meaningfully -redefined, this is specified for each in the next section.

-
-

Important

-

Global parameters must not be defined in a directory subsection, -else they will not be found at all by the RCL code, which looks for -them at the top level (e.g. skippedPaths).

-
-

When found at the beginning of a file path, the tilde character (~) is -expanded to the name of the user’s home directory, as a shell would do.

-

Some parameters are lists of strings. White space is used for -separation. List elements with embedded spaces can be quoted using -double-quotes. Double quotes inside these elements can be escaped with a -backslash.

-

No value inside a configuration file can contain a newline character. -Long lines can be continued by escaping the physical newline with -backslash, even inside quoted strings.

-
astringlist =  "some string \
-with spaces"
-thesame = "some string with spaces"
-
-
-

Parameters which are not part of string lists can’t be quoted, and -leading and trailing space characters are stripped before the value is -used.

-

Encoding issues.

-

Most of the configuration parameters are plain ASCII. Two particular -sets of values may cause encoding issues:

-
    -
  • File path parameters may contain non-ascii characters and should use -the exact same byte values as found in the file system directory. -Usually, this means that the configuration file should use the system -default locale encoding.
  • -
  • The unac_except_trans parameter should be encoded in UTF-8. If your -system locale is not UTF-8, and you need to also specify non-ascii -file paths, this poses a difficulty because common text editors -cannot handle multiple encodings in a single file. In this relatively -unlikely case, you can edit the configuration file as two separate -text files with appropriate encodings, and concatenate them to create -the complete configuration.
  • -
-
-

Environment variables

-
-
RECOLL_CONFDIR
-
Defines the main configuration directory.
-
RECOLL_TMPDIR, TMPDIR
-
Locations for temporary files, in this order of priority. The -default if none of these is set is to use /tmp. Big temporary -files may be created during indexing, mostly for decompressing, and -also for processing, e.g. email attachments.
-
RECOLL_CONFTOP, RECOLL_CONFMID
-
Allow adding configuration directories with priorities below and -above the user directory (see above the Configuration overview -section for details).
-
RECOLL_EXTRA_DBS, RECOLL_ACTIVE_EXTRA_DBS
-
Help for setting up external indexes. See this -paragraph for explanations.
-
RECOLL_DATADIR
-
Defines replacement for the default location of Recoll data files, -normally found in, e.g., /usr/share/recoll).
-
RECOLL_FILTERSDIR
-
Defines replacement for the default location of Recoll filters, -normally found in, e.g., /usr/share/recoll/filters).
-
ASPELL_PROG
-
aspell program to use for creating the spelling dictionary. The -result has to be compatible with the libaspell which RCL is -using.
-
VARNAME
-
Blabla
-
-
-
-

Recoll main configuration file, recoll.conf

-
-
Parameters affecting what documents we index
-
-
topdirs
-
Space-separated list of files or directories to recursively index. -Default to ~ (indexes $HOME). You can use symbolic links in the -list, they will be followed, independantly of the value of the -followLinks variable.
-
monitordirs
-
Space-separated list of files or directories to monitor for updates. -When running the real-time indexer, this allows monitoring only a -subset of the whole indexed area. The elements must be included in -the tree defined by the ‘topdirs’ members.
-
skippedNames
-
Files and directories which should be ignored. White space separated -list of wildcard patterns (simple ones, not paths, must contain no / -), which will be tested against file and directory names. The list -in the default configuration does not exclude hidden directories -(names beginning with a dot), which means that it may index quite a -few things that you do not want. On the other hand, email user -agents like Thunderbird usually store messages in hidden -directories, and you probably want this indexed. One possible -solution is to have ”.*” in “skippedNames”, and add things like -“~/.thunderbird” “~/.evolution” to “topdirs”. Not even the file -names are indexed for patterns in this list, see the -“noContentSuffixes” variable for an alternative approach which -indexes the file names. Can be redefined for any subtree.
-
skippedNames-
-
List of name endings to remove from the default skippedNames list.
-
skippedNames+
-
List of name endings to add to the default skippedNames list.
-
noContentSuffixes
-
List of name endings (not necessarily dot-separated suffixes) for -which we don’t try MIME type identification, and don’t uncompress or -index content. Only the names will be indexed. This complements the -now obsoleted recoll_noindex list from the mimemap file, which will -go away in a future release (the move from mimemap to recoll.conf -allows editing the list through the GUI). This is different from -skippedNames because these are name ending matches only (not -wildcard patterns), and the file name itself gets indexed normally. -This can be redefined for subdirectories.
-
noContentSuffixes-
-
List of name endings to remove from the default noContentSuffixes -list.
-
noContentSuffixes+
-
List of name endings to add to the default noContentSuffixes list.
-
skippedPaths
-
Absolute paths we should not go into. Space-separated list of -wildcard expressions for absolute filesystem paths. Must be defined -at the top level of the configuration file, not in a subsection. Can -contain files and directories. The database and configuration -directories will automatically be added. The expressions are matched -using ‘fnmatch(3)’ with the FNM_PATHNAME flag set by default. This -means that ‘/’ characters must be matched explicitely. You can set -‘skippedPathsFnmPathname’ to 0 to disable the use of FNM_PATHNAME -(meaning that ‘/*/dir3’ will match ‘/dir1/dir2/dir3’). The default -value contains the usual mount point for removable media to remind -you that it is a bad idea to have Recoll work on these (esp. with -the monitor: media gets indexed on mount, all data gets erased on -unmount). Explicitely adding ‘/media/xxx’ to the ‘topdirs’ variable -will override this.
-
skippedPathsFnmPathname
-
Set to 0 to override use of FNM_PATHNAME for matching skipped -paths.
-
nowalkfn
-
File name which will cause its parent directory to be skipped. Any -directory containing a file with this name will be skipped as if it -was part of the skippedPaths list. Ex: .recoll-noindex
-
daemSkippedPaths
-
skippedPaths equivalent specific to real time indexing. This enables -having parts of the tree which are initially indexed but not -monitored. If daemSkippedPaths is not set, the daemon uses -skippedPaths.
-
zipUseSkippedNames
-
Use skippedNames inside Zip archives. Fetched directly by the rclzip -handler. Skip the patterns defined by skippedNames inside Zip -archives. Can be redefined for subdirectories. See -https://www.lesbonscomptes.com/recoll/faqsandhowtos/FilteringOutZipArchiveMembers.html
-
zipSkippedNames
-
Space-separated list of wildcard expressions for names that should -be ignored inside zip archives. This is used directly by the zip -handler. If zipUseSkippedNames is not set, zipSkippedNames defines -the patterns to be skipped inside archives. If zipUseSkippedNames is -set, the two lists are concatenated and used. Can be redefined for -subdirectories. See -https://www.lesbonscomptes.com/recoll/faqsandhowtos/FilteringOutZipArchiveMembers.html
-
followLinks
-
Follow symbolic links during indexing. The default is to ignore -symbolic links to avoid multiple indexing of linked files. No effort -is made to avoid duplication when this option is set to true. This -option can be set individually for each of the ‘topdirs’ members by -using sections. It can not be changed below the ‘topdirs’ level. -Links in the ‘topdirs’ list itself are always followed.
-
indexedmimetypes
-
Restrictive list of indexed mime types. Normally not set (in which -case all supported types are indexed). If it is set, only the types -from the list will have their contents indexed. The names will be -indexed anyway if indexallfilenames is set (default). MIME type -names should be taken from the mimemap file (the values may be -different from xdg-mime or file -i output in some cases). Can be -redefined for subtrees.
-
excludedmimetypes
-
List of excluded MIME types. Lets you exclude some types from -indexing. MIME type names should be taken from the mimemap file (the -values may be different from xdg-mime or file -i output in some -cases) Can be redefined for subtrees.
-
nomd5types
-
Don’t compute md5 for these types. md5 checksums are used only for -deduplicating results, and can be very expensive to compute on -multimedia or other big files. This list lets you turn off md5 -computation for selected types. It is global (no redefinition for -subtrees). At the moment, it only has an effect for external -handlers (exec and execm). The file types can be specified by -listing either MIME types (e.g. audio/mpeg) or handler names (e.g. -rclaudio).
-
compressedfilemaxkbs
-
Size limit for compressed files. We need to decompress these in a -temporary directory for identification, which can be wasteful in -some cases. Limit the waste. Negative means no limit. 0 results in -no processing of any compressed file. Default 50 MB.
-
textfilemaxmbs
-
Size limit for text files. Mostly for skipping monster logs. Default -20 MB.
-
indexallfilenames
-
Index the file names of unprocessed files Index the names of files -the contents of which we don’t index because of an excluded or -unsupported MIME type.
-
usesystemfilecommand
-
Use a system command for file MIME type guessing as a final step in -file type identification This is generally useful, but will usually -cause the indexing of many bogus ‘text’ files. See -‘systemfilecommand’ for the command used.
-
systemfilecommand
-
Command used to guess MIME types if the internal methods fails This -should be a “file -i” workalike. The file path will be added as a -last parameter to the command line. ‘xdg-mime’ works better than the -traditional ‘file’ command, and is now the configured default (with -a hard-coded fallback to ‘file’)
-
processwebqueue
-
Decide if we process the Web queue. The queue is a directory where -the Recoll Web browser plugins create the copies of visited pages.
-
textfilepagekbs
-
Page size for text files. If this is set, text/plain files will be -divided into documents of approximately this size. Will reduce -memory usage at index time and help with loading data in the preview -window at query time. Particularly useful with very big files, such -as application or system logs. Also see textfilemaxmbs and -compressedfilemaxkbs.
-
membermaxkbs
-
Size limit for archive members. This is passed to the filters in the -environment as RECOLL_FILTER_MAXMEMBERKB.
-
-
-
-
Parameters affecting how we generate terms and organize the index
-
-
indexStripChars
-
Decide if we store character case and diacritics in the index. If we -do, searches sensitive to case and diacritics can be performed, but -the index will be bigger, and some marginal weirdness may sometimes -occur. The default is a stripped index. When using multiple indexes -for a search, this parameter must be defined identically for all. -Changing the value implies an index reset.
-
indexStoreDocText
-
Decide if we store the documents’ text content in the index. Storing -the text allows extracting snippets from it at query time, instead -of building them from index position data. Newer Xapian index -formats have rendered our use of positions list unacceptably slow in -some cases. The last Xapian index format with good performance for -the old method is Chert, which is default for 1.2, still supported -but not default in 1.4 and will be dropped in 1.6. The stored -document text is translated from its original format to UTF-8 plain -text, but not stripped of upper-case, diacritics, or punctuation -signs. Storing it increases the index size by 10-20% typically, but -also allows for nicer snippets, so it may be worth enabling it even -if not strictly needed for performance if you can afford the space. -The variable only has an effect when creating an index, meaning that -the xapiandb directory must not exist yet. Its exact effect depends -on the Xapian version. For Xapian 1.4, if the variable is set to 0, -the Chert format will be used, and the text will not be stored. If -the variable is 1, Glass will be used, and the text stored. For -Xapian 1.2, and for versions after 1.5 and newer, the index format -is always the default, but the variable controls if the text is -stored or not, and the abstract generation method. With Xapian 1.5 -and later, and the variable set to 0, abstract generation may be -very slow, but this setting may still be useful to save space if you -do not use abstract generation at all.
-
nonumbers
-
Decides if terms will be generated for numbers. For example “123”, -“1.5e6”, 192.168.1.4, would not be indexed if nonumbers is set -(“value123” would still be). Numbers are often quite interesting to -search for, and this should probably not be set except for special -situations, ie, scientific documents with huge amounts of numbers in -them, where setting nonumbers will reduce the index size. This can -only be set for a whole index, not for a subtree.
-
dehyphenate
-
Determines if we index ‘coworker’ also when the input is -‘co-worker’. This is new in version 1.22, and on by default. Setting -the variable to off allows restoring the previous behaviour.
-
backslashasletter
-
Process backslash as normal letter This may make sense for people -wanting to index TeX commands as such but is not of much general -use.
-
maxtermlength
-
Maximum term length. Words longer than this will be discarded. The -default is 40 and used to be hard-coded, but it can now be adjusted. -You need an index reset if you change the value.
-
nocjk
-
Decides if specific East Asian (Chinese Korean Japanese) -characters/word splitting is turned off. This will save a small -amount of CPU if you have no CJK documents. If your document base -does include such text but you are not interested in searching it, -setting nocjk may be a significant time and space saver.
-
cjkngramlen
-
This lets you adjust the size of n-grams used for indexing CJK text. -The default value of 2 is probably appropriate in most cases. A -value of 3 would allow more precision and efficiency on longer -words, but the index will be approximately twice as large.
-
indexstemminglanguages
-
Languages for which to create stemming expansion data. Stemmer names -can be found by executing ‘recollindex -l’, or this can also be set -from a list in the GUI.
-
defaultcharset
-
Default character set. This is used for files which do not contain a -character set definition (e.g.: text/plain). Values found inside -files, e.g. a ‘charset’ tag in HTML documents, will override it. If -this is not set, the default character set is the one defined by the -NLS environment ($LC_ALL, $LC_CTYPE, $LANG), or ultimately -iso-8859-1 (cp-1252 in fact). If for some reason you want a general -default which does not match your LANG and is not 8859-1, use this -variable. This can be redefined for any sub-directory.
-
unac_except_trans
-
A list of characters, encoded in UTF-8, which should be handled -specially when converting text to unaccented lowercase. For example, -in Swedish, the letter a with diaeresis has full alphabet -citizenship and should not be turned into an a. Each element in the -space-separated list has the special character as first element and -the translation following. The handling of both the lowercase and -upper-case versions of a character should be specified, as -appartenance to the list will turn-off both standard accent and case -processing. The value is global and affects both indexing and -querying. Examples: Swedish: unac_except_trans = ää Ää öö Öö üü Üü -ßss œoe Œoe æae Æae ffff fifi flfl åå Åå . German: unac_except_trans -= ää Ää öö Öö üü Üü ßss œoe Œoe æae Æae ffff fifi flfl In French, you -probably want to decompose oe and ae and nobody would type a German -ß unac_except_trans = ßss œoe Œoe æae Æae ffff fifi flfl . The -default for all until someone protests follows. These decompositions -are not performed by unac, but it is unlikely that someone would -type the composed forms in a search. unac_except_trans = ßss œoe -Œoe æae Æae ffff fifi flfl
-
maildefcharset
-
Overrides the default character set for email messages which don’t -specify one. This is mainly useful for readpst (libpst) dumps, which -are utf-8 but do not say so.
-
localfields
-
Set fields on all files (usually of a specific fs area). Syntax is -the usual: name = value ; attr1 = val1 ; [...] value is empty so -this needs an initial semi-colon. This is useful, e.g., for setting -the rclaptg field for application selection inside mimeview.
-
testmodifusemtime
-
Use mtime instead of ctime to test if a file has been modified. The -time is used in addition to the size, which is always used. Setting -this can reduce re-indexing on systems where extended attributes are -used (by some other application), but not indexed, because changing -extended attributes only affects ctime. Notes: - This may prevent -detection of change in some marginal file rename cases (the target -would need to have the same size and mtime). - You should probably -also set noxattrfields to 1 in this case, except if you still prefer -to perform xattr indexing, for example if the local file update -pattern makes it of value (as in general, there is a risk for pure -extended attributes updates without file modification to go -undetected). Perform a full index reset after changing this.
-
noxattrfields
-
Disable extended attributes conversion to metadata fields. This -probably needs to be set if testmodifusemtime is set.
-
metadatacmds
-
Define commands to gather external metadata, e.g. tmsu tags. There -can be several entries, separated by semi-colons, each defining -which field name the data goes into and the command to use. Don’t -forget the initial semi-colon. All the field names must be -different. You can use aliases in the “field” file if necessary. As -a not too pretty hack conceded to convenience, any field name -beginning with “rclmulti” will be taken as an indication that the -command returns multiple field values inside a text blob formatted -as a recoll configuration file (“fieldname = fieldvalue” lines). The -rclmultixx name will be ignored, and field names and values will be -parsed from the data. Example: metadatacmds = ; tags = tmsu tags %f; -rclmulti1 = cmdOutputsConf %f
-
-
-
-
Parameters affecting where and how we store things
-
-
cachedir
-
Top directory for Recoll data. Recoll data directories are normally -located relative to the configuration directory (e.g. -~/.recoll/xapiandb, ~/.recoll/mboxcache). If ‘cachedir’ is set, the -directories are stored under the specified value instead (e.g. if -cachedir is ~/.cache/recoll, the default dbdir would be -~/.cache/recoll/xapiandb). This affects dbdir, webcachedir, -mboxcachedir, aspellDicDir, which can still be individually -specified to override cachedir. Note that if you have multiple -configurations, each must have a different cachedir, there is no -automatic computation of a subpath under cachedir.
-
maxfsoccuppc
-
Maximum file system occupation over which we stop indexing. The -value is a percentage, corresponding to what the “Capacity” df -output column shows. The default value is 0, meaning no checking.
-
dbdir
-
Xapian database directory location. This will be created on first -indexing. If the value is not an absolute path, it will be -interpreted as relative to cachedir if set, or the configuration -directory (-c argument or $RECOLL_CONFDIR). If nothing is -specified, the default is then ~/.recoll/xapiandb/
-
idxstatusfile
-
Name of the scratch file where the indexer process updates its -status. Default: idxstatus.txt inside the configuration directory.
-
mboxcachedir
-
Directory location for storing mbox message offsets cache files. -This is normally ‘mboxcache’ under cachedir if set, or else under -the configuration directory, but it may be useful to share a -directory between different configurations.
-
mboxcacheminmbs
-
Minimum mbox file size over which we cache the offsets. There is -really no sense in caching offsets for small files. The default is 5 -MB.
-
webcachedir
-
Directory where we store the archived web pages. This is only used -by the web history indexing code Default: cachedir/webcache if -cachedir is set, else $RECOLL_CONFDIR/webcache
-
webcachemaxmbs
-
Maximum size in MB of the Web archive. This is only used by the web -history indexing code. Default: 40 MB. Reducing the size will not -physically truncate the file.
-
webqueuedir
-
The path to the Web indexing queue. This used to be hard-coded in -the old plugin as ~/.recollweb/ToIndex so there would be no need or -possibility to change it, but the WebExtensions plugin now downloads -the files to the user Downloads directory, and a script moves them -to webqueuedir. The script reads this value from the config so it -has become possible to change it.
-
webdownloadsdir
-
The path to browser downloads directory. This is where the new -browser add-on extension has to create the files. They are then -moved by a script to webqueuedir.
-
aspellDicDir
-
Aspell dictionary storage directory location. The aspell dictionary -(aspdict.(lang).rws) is normally stored in the directory specified -by cachedir if set, or under the configuration directory.
-
filtersdir
-
Directory location for executable input handlers. If -RECOLL_FILTERSDIR is set in the environment, we use it instead. -Defaults to $prefix/share/recoll/filters. Can be redefined for -subdirectories.
-
iconsdir
-
Directory location for icons. The only reason to change this would -be if you want to change the icons displayed in the result list. -Defaults to $prefix/share/recoll/images
-
-
-
-
Parameters affecting indexing performance and resource usage
-
-
idxflushmb
-
Threshold (megabytes of new data) where we flush from memory to disk -index. Setting this allows some control over memory usage by the -indexer process. A value of 0 means no explicit flushing, which lets -Xapian perform its own thing, meaning flushing every -$XAPIAN_FLUSH_THRESHOLD documents created, modified or deleted: as -memory usage depends on average document size, not only document -count, the Xapian approach is is not very useful, and you should let -Recoll manage the flushes. The program compiled value is 0. The -configured default value (from this file) is now 50 MB, and should -be ok in many cases. You can set it as low as 10 to conserve memory, -but if you are looking for maximum speed, you may want to experiment -with values between 20 and 200. In my experience, values beyond this -are always counterproductive. If you find otherwise, please drop me -a note.
-
filtermaxseconds
-
Maximum external filter execution time in seconds. Default 1200 -(20mn). Set to 0 for no limit. This is mainly to avoid infinite -loops in postscript files (loop.ps)
-
filtermaxmbytes
-
Maximum virtual memory space for filter processes -(setrlimit(RLIMIT_AS)), in megabytes. Note that this includes any -mapped libs (there is no reliable Linux way to limit the data space -only), so we need to be a bit generous here. Anything over 2000 will -be ignored on 32 bits machines.
-
thrQSizes
-
Stage input queues configuration. There are three internal queues in -the indexing pipeline stages (file data extraction, terms -generation, index update). This parameter defines the queue depths -for each stage (three integer values). If a value of -1 is given for -a given stage, no queue is used, and the thread will go on -performing the next stage. In practise, deep queues have not been -shown to increase performance. Default: a value of 0 for the first -queue tells Recoll to perform autoconfiguration based on the -detected number of CPUs (no need for the two other values in this -case). Use thrQSizes = -1 -1 -1 to disable multithreading entirely.
-
thrTCounts
-
Number of threads used for each indexing stage. The three stages -are: file data extraction, terms generation, index update). The use -of the counts is also controlled by some special values in -thrQSizes: if the first queue depth is 0, all counts are ignored -(autoconfigured); if a value of -1 is used for a queue depth, the -corresponding thread count is ignored. It makes no sense to use a -value other than 1 for the last stage because updating the Xapian -index is necessarily single-threaded (and protected by a mutex).
-
-
-
-
Miscellaneous parameters
-
-
loglevel
-
Log file verbosity 1-6. A value of 2 will print only errors and -warnings. 3 will print information like document updates, 4 is quite -verbose and 6 very verbose.
-
logfilename
-
Log file destination. Use ‘stderr’ (default) to write to the -console.
-
idxloglevel
-
Override loglevel for the indexer.
-
idxlogfilename
-
Override logfilename for the indexer.
-
daemloglevel
-
Override loglevel for the indexer in real time mode. The default is -to use the idx... values if set, else the log... values.
-
daemlogfilename
-
Override logfilename for the indexer in real time mode. The default -is to use the idx... values if set, else the log... values.
-
orgidxconfdir
-
Original location of the configuration directory. This is used -exclusively for movable datasets. Locating the configuration -directory inside the directory tree makes it possible to provide -automatic query time path translations once the data set has moved -(for example, because it has been mounted on another location).
-
curidxconfdir
-
Current location of the configuration directory. Complement -orgidxconfdir for movable datasets. This should be used if the -configuration directory has been copied from the dataset to another -location, either because the dataset is readonly and an r/w copy is -desired, or for performance reasons. This records the original moved -location before copy, to allow path translation computations. For -example if a dataset originally indexed as ‘/home/me/mydata/config’ -has been mounted to ‘/media/me/mydata’, and the GUI is running from -a copied configuration, orgidxconfdir would be -‘/home/me/mydata/config’, and curidxconfdir (as set in the copied -configuration) would be ‘/media/me/mydata/config’.
-
idxrundir
-
Indexing process current directory. The input handlers sometimes -leave temporary files in the current directory, so it makes sense to -have recollindex chdir to some temporary directory. If the value is -empty, the current directory is not changed. If the value is -(literal) tmp, we use the temporary directory as set by the -environment (RECOLL_TMPDIR else TMPDIR else /tmp). If the value is -an absolute path to a directory, we go there.
-
checkneedretryindexscript
-
Script used to heuristically check if we need to retry indexing -files which previously failed. The default script checks the -modified dates on /usr/bin and /usr/local/bin. A relative path will -be looked up in the filters dirs, then in the path. Use an absolute -path to do otherwise.
-
recollhelperpath
-
Additional places to search for helper executables. This is only -used on Windows for now.
-
idxabsmlen
-
Length of abstracts we store while indexing. Recoll stores an -abstract for each indexed file. The text can come from an actual -‘abstract’ section in the document or will just be the beginning of -the document. It is stored in the index so that it can be displayed -inside the result lists without decoding the original file. The -idxabsmlen parameter defines the size of the stored abstract. The -default value is 250 bytes. The search interface gives you the -choice to display this stored text or a synthetic abstract built by -extracting text around the search terms. If you always prefer the -synthetic abstract, you can reduce this value and save a little -space.
-
idxmetastoredlen
-
Truncation length of stored metadata fields. This does not affect -indexing (the whole field is processed anyway), just the amount of -data stored in the index for the purpose of displaying fields inside -result lists or previews. The default value is 150 bytes which may -be too low if you have custom fields.
-
idxtexttruncatelen
-
Truncation length for all document texts. Only index the beginning -of documents. This is not recommended except if you are sure that -the interesting keywords are at the top and have severe disk space -issues.
-
aspellLanguage
-
Language definitions to use when creating the aspell dictionary. The -value must match a set of aspell language definition files. You can -type “aspell dicts” to see a list The default if this is not set is -to use the NLS environment to guess the value.
-
aspellAddCreateParam
-
Additional option and parameter to aspell dictionary creation -command. Some aspell packages may need an additional option (e.g. on -Debian Jessie: –local-data-dir=/usr/lib/aspell). See Debian bug -772415.
-
aspellKeepStderr
-
Set this to have a look at aspell dictionary creation errors. There -are always many, so this is mostly for debugging.
-
noaspell
-
Disable aspell use. The aspell dictionary generation takes time, and -some combinations of aspell version, language, and local terms, -result in aspell crashing, so it sometimes makes sense to just -disable the thing.
-
monauxinterval
-
Auxiliary database update interval. The real time indexer only -updates the auxiliary databases (stemdb, aspell) periodically, -because it would be too costly to do it for every document change. -The default period is one hour.
-
monixinterval
-
Minimum interval (seconds) between processings of the indexing -queue. The real time indexer does not process each event when it -comes in, but lets the queue accumulate, to diminish overhead and to -aggregate multiple events affecting the same file. Default 30 S.
-
mondelaypatterns
-
Timing parameters for the real time indexing. Definitions for files -which get a longer delay before reindexing is allowed. This is for -fast-changing files, that should only be reindexed once in a while. -A list of wildcardPattern:seconds pairs. The patterns are matched -with fnmatch(pattern, path, 0) You can quote entries containing -white space with double quotes (quote the whole entry, not the -pattern). The default is empty. Example: mondelaypatterns = -*.log:20 “*with spaces.*:30”
-
monioniceclass
-
ionice class for the real time indexing process On platforms where -this is supported. The default value is 3.
-
monioniceclassdata
-
ionice class parameter for the real time indexing process. On -platforms where this is supported. The default is empty.
-
-
-
-
Query-time parameters (no impact on the index)
-
-
autodiacsens
-
auto-trigger diacritics sensitivity (raw index only). IF the index -is not stripped, decide if we automatically trigger diacritics -sensitivity if the search term has accented characters (not in -unac_except_trans). Else you need to use the query language and -the “D” modifier to specify diacritics sensitivity. Default is no.
-
autocasesens
-
auto-trigger case sensitivity (raw index only). IF the index is not -stripped (see indexStripChars), decide if we automatically trigger -character case sensitivity if the search term has upper-case -characters in any but the first position. Else you need to use the -query language and the “C” modifier to specify character-case -sensitivity. Default is yes.
-
maxTermExpand
-
Maximum query expansion count for a single term (e.g.: when using -wildcards). This only affects queries, not indexing. We used to not -limit this at all (except for filenames where the limit was too low -at 1000), but it is unreasonable with a big index. Default 10000.
-
maxXapianClauses
-
Maximum number of clauses we add to a single Xapian query. This only -affects queries, not indexing. In some cases, the result of term -expansion can be multiplicative, and we want to avoid eating all the -memory. Default 50000.
-
snippetMaxPosWalk
-
Maximum number of positions we walk while populating a snippet for -the result list. The default of 1,000,000 may be insufficient for -very big documents, the consequence would be snippets with possibly -meaning-altering missing words.
-
-
-
-
Parameters for the PDF input script
-
-
pdfocr
-
Attempt OCR of PDF files with no text content if both tesseract and -pdftoppm are installed. The default is off because OCR is so very -slow.
-
pdfocrlang
-
Language to assume for PDF OCR. This is very important for having a -reasonable rate of errors with tesseract. This can also be set -through a configuration variable or directory-local parameters. See -the rclpdf.py script.
-
pdfattach
-
Enable PDF attachment extraction by executing pdftk (if available). -This is normally disabled, because it does slow down PDF indexing a -bit even if not one attachment is ever found.
-
pdfextrameta
-
Extract text from selected XMP metadata tags. This is a -space-separated list of qualified XMP tag names. Each element can -also include a translation to a Recoll field name, separated by a -‘|’ character. If the second element is absent, the tag name is -used as the Recoll field names. You will also need to add -specifications to the ‘fields’ file to direct processing of the -extracted data.
-
pdfextrametafix
-
Define name of XMP field editing script. This defines the name of a -script to be loaded for editing XMP field values. The script should -define a ‘MetaFixer’ class with a metafix() method which will be -called with the qualified tag name and value of each selected field, -for editing or erasing. A new instance is created for each document, -so that the object can keep state for, e.g. eliminating duplicate -values.
-
-
-
-
Parameters set for specific locations
-
-
mhmboxquirks
-
Enable thunderbird/mozilla-seamonkey mbox format quirks Set this for -the directory where the email mbox files are stored.
-
-
-
-
-

The fields file

-

This file contains information about dynamic fields handling in RCL. -Some very basic fields have hard-wired behaviour, and, mostly, you -should not change the original data inside the fields file. But you -can create custom fields fitting your data and handle them just like -they were native ones.

-

The fields file has several sections, which each define an aspect of -fields processing. Quite often, you’ll have to modify several sections -to obtain the desired behaviour.

-

We will only give a short description here, you should refer to the -comments inside the default file for more detailed information.

-

Field names should be lowercase alphabetic ASCII.

-
-
[prefixes]
-
A field becomes indexed (searchable) by having a prefix defined in -this section. There is a more complete explanation of what prefixes -are in used by a standard recoll installation. In a nutshell: -extension prefixes should be all caps, begin with XY, and short. -E.g. XYMFLD.
-
[values]
-
Fields listed in this section will be stored as XAP values -inside the index. This makes them available for range queries, -allowing to filter results according to the field value. This -feature currently supports string and integer data. See the comments -in the file for more detail
-
[stored]
-
A field becomes stored (displayable inside results) by having its -name listed in this section (typically with an empty value).
-
[aliases]
-
This section defines lists of synonyms for the canonical names used -inside the [prefixes] and [stored] sections
-
[queryaliases]
-
This section also defines aliases for the canonic field names, with -the difference that the substitution will only be used at query -time, avoiding any possibility that the value would pick-up random -metadata from documents.
-
handler-specific sections
-
Some input handlers may need specific configuration for handling -fields. Only the email message handler currently has such a section -(named [mail]). It allows indexing arbitrary email headers in -addition to the ones indexed by default. Other such sections may -appear in the future.
-
-

Here follows a small example of a personal fields file. This would -extract a specific email header and use it as a searchable field, with -data displayable inside result lists. (Side note: as the email handler -does no decoding on the values, only plain ascii headers can be indexed, -and only the first occurrence will be used for headers that occur -several times).

-
[prefixes]
-        # Index mailmytag contents (with the given prefix)
-        mailmytag = XMTAG
-
-        [stored]
-        # Store mailmytag inside the document data record (so that it can be
-        # displayed - as %(mailmytag) - in result lists).
-        mailmytag =
-
-        [queryaliases]
-        filename = fn
-        containerfilename = cfn
-
-        [mail]
-        # Extract the X-My-Tag mail header, and use it internally with the
-        # mailmytag field name
-        x-my-tag = mailmytag
-
-
-
-
Extended attributes in the fields file
-

RCL versions 1.19 and later process user extended file attributes as -documents fields by default.

-

Attributes are processed as fields of the same name, after removing the -user prefix on Linux.

-

The [xattrtofields] section of the fields file allows specifying -translations from extended attributes names to RCL field names. An empty -translation disables use of the corresponding attribute data.

-
-
-
-

The mimemap file

-

mimemap specifies the file name extension to MIME type mappings.

-

For file names without an extension, or with an unknown one, a system -command (file -i, or xdg-mime) will be executed to determine -the MIME type (this can be switched off, or the command changed inside -the main configuration file).

-

All extension values in mimemap must be entered in lower case. File -names extensions are lower-cased for comparison during indexing, meaning -that an upper case mimemap entry will never be matched.

-

The mappings can be specified on a per-subtree basis, which may be -useful in some cases. Example: okular notes have a .xml extension -but should be handled specially, which is possible because they are -usually all located in one place. Example:

-
[~/.kde/share/apps/okular/docdata]
-        .xml = application/x-okular-notes
-
-
-

The recoll_noindex mimemap variable has been moved to -recoll.conf and renamed to noContentSuffixes, while keeping the -same function, as of RCL version 1.21. For older RCL versions, see the -documentation for noContentSuffixes but use recoll_noindex in -mimemap.

-
-
-

The mimeconf file

-

The main purpose of the mimeconf file is to specify how the -different MIME types are handled for indexing. This is done in the -[index] section, which should not be modified casually. See the -comments in the file.

-

The file also contains other definitions which affect the query language -and the GUI, and which, in retrospect, should have been stored -elsewhere.

-

The [icons] section allows you to change the icons which are -displayed by the recoll GUI in the result lists (the values are the -basenames of the png images inside the iconsdir directory (which -is itself defined in recoll.conf).

-

The [categories] section defines the groupings of MIME types into -categories as used when adding an rclcat clause to a query -language query. rclcat clauses are also used -by the default guifilters buttons in the GUI (see next).

-

The filter controls appear at the top of the recoll GUI, either as -checkboxes just above the result list, or as a dropbox in the tool area.

-

By default, they are labeled: media, message, other, -presentation, spreadsheet and text, and each maps to a -document category. This is determined in the [guifilters] section, -where each control is defined by a variable naming a query language -fragment.

-

A simple exemple will hopefully make things clearer.

-
[guifilters]
-
-Big Books = dir:"~/My Books" size>10K
-My Docs = dir:"~/My Documents"
-Small Books = dir:"~/My Books" size<10K
-System Docs = dir:/usr/share/doc
-
-
-

The above definition would create four filter checkboxes, labelled -Big Books, My Docs, etc.

-

The text after the equal sign must be a valid query language fragment, -and, when the button is checked, it will be combined with the rest of -the query with an AND conjunction.

-

Any name text before a colon character will be erased in the display, -but used for sorting. You can use this to display the checkboxes in any -order you like. For exemple, the following would do exactly the same as -above, but ordering the checkboxes in the reverse order.

-
[guifilters]
-
-d:Big Books = dir:"~/My Books" size>10K
-c:My Docs = dir:"~/My Documents"
-b:Small Books = dir:"~/My Books" size<10K
-a:System Docs = dir:/usr/share/doc
-
-
-

As you may have guessed, The default [guifilters] section looks -like:

-
[guifilters]
-text = rclcat:text
-spreadsheet = rclcat:spreadsheet
-presentation = rclcat:presentation
-media = rclcat:media
-message = rclcat:message
-other = rclcat:other
-
-
-
-
-

The mimeview file

-

mimeview specifies which programs are started when you click on an -Open link in a result list. Ie: HTML is normally displayed using -firefox, but you may prefer Konqueror, your openoffice.org program might -be named oofice instead of openoffice etc.

-

Changes to this file can be done by direct editing, or through the -recoll GUI preferences dialog.

-

If Use desktop preferences to choose document editor is checked in the -RCL GUI preferences, all mimeview entries will be ignored except the -one labelled application/x-all (which is set to use xdg-open by -default).

-

In this case, the xallexcepts top level variable defines a list of -MIME type exceptions which will be processed according to the local -entries instead of being passed to the desktop. This is so that specific -RCL options such as a page number or a search string can be passed to -applications that support them, such as the evince viewer.

-

As for the other configuration files, the normal usage is to have a -mimeview inside your own configuration directory, with just the -non-default entries, which will override those from the central -configuration file.

-

All viewer definition entries must be placed under a [view] section.

-

The keys in the file are normally MIME types. You can add an application -tag to specialize the choice for an area of the filesystem (using a -localfields specification in mimeconf). The syntax for the key -is mimetype|tag

-

The nouncompforviewmts entry, (placed at the top level, outside of -the [view] section), holds a list of MIME types that should not be -uncompressed before starting the viewer (if they are found compressed, -ie: mydoc.doc.gz).

-

The right side of each assignment holds a command to be executed for -opening the file. The following substitutions are performed:

-
    -
  • %D.

    -

    Document date

    -
  • -
  • %f.

    -

    File name. This may be the name of a temporary file if it was -necessary to create one (ie: to extract a subdocument from a -container).

    -
  • -
  • %i.

    -

    Internal path, for subdocuments of containers. The format depends on -the container type. If this appears in the command line, RCL will not -create a temporary file to extract the subdocument, expecting the -called application (possibly a script) to be able to handle it.

    -
  • -
  • %M.

    -

    MIME type

    -
  • -
  • %p.

    -

    Page index. Only significant for a subset of document types, -currently only PDF, Postscript and DVI files. Can be used to start -the editor at the right page for a match or snippet.

    -
  • -
  • %s.

    -

    Search term. The value will only be set for documents with indexed -page numbers (ie: PDF). The value will be one of the matched search -terms. It would allow pre-setting the value in the “Find” entry -inside Evince for example, for easy highlighting of the term.

    -
  • -
  • %u.

    -

    Url.

    -
  • -
-

In addition to the predefined values above, all strings like -%(fieldname) will be replaced by the value of the field named -fieldname for the document. This could be used in combination with -field customisation to help with opening the document.

-
-
-

The ptrans file

-

ptrans specifies query-time path translations. These can be useful -in multiple cases.

-

The file has a section for any index which needs translations, either -the main one or additional query indexes. The sections are named with -the XAP index directory names. No slash character should exist at the -end of the paths (all comparisons are textual). An exemple should make -things sufficiently clear

-
[/home/me/.recoll/xapiandb]
-/this/directory/moved = /to/this/place
-
-[/path/to/additional/xapiandb]
-/server/volume1/docdir = /net/server/volume1/docdir
-/server/volume2/docdir = /net/server/volume2/docdir
-
-
-
-
-

Examples of configuration adjustments

-
-
Adding an external viewer for an non-indexed type
-

Imagine that you have some kind of file which does not have indexable -content, but for which you would like to have a functional Open link in -the result list (when found by file name). The file names end in .blob -and can be displayed by application blobviewer.

-

You need two entries in the configuration files for this to work:

-
    -
  • In $RECOLL_CONFDIR/mimemap (typically ~/.recoll/mimemap), add -the following line:

    -
    .blob = application/x-blobapp
    -
    -
    -

    Note that the MIME type is made up here, and you could call it -diesel/oil just the same.

    -
  • -
  • In $RECOLL_CONFDIR/mimeview under the [view] section, add:

    -
    application/x-blobapp = blobviewer %f
    -
    -
    -

    We are supposing that blobviewer wants a file name parameter here, -you would use %u if it liked URLs better.

    -
  • -
-

If you just wanted to change the application used by RCL to display a -MIME type which it already knows, you would just need to edit -mimeview. The entries you add in your personal file override those -in the central configuration, which you do not need to alter. -mimeview can also be modified from the Gui.

-
-
-
Adding indexing support for a new file type
-

Let us now imagine that the above .blob files actually contain indexable -text and that you know how to extract it with a command line program. -Getting RCL to index the files is easy. You need to perform the above -alteration, and also to add data to the mimeconf file (typically in -~/.recoll/mimeconf):

-
    -
  • Under the [index] section, add the following line (more about the -rclblob indexing script later):

    -
    application/x-blobapp = exec rclblob
    -
    -
    -

    Or if the files are mostly text and you don’t need to process them -for indexing:

    -
    application/x-blobapp = internal text/plain
    -
    -
    -
  • -
  • Under the [icons] section, you should choose an icon to be -displayed for the files inside the result lists. Icons are normally -64x64 pixels PNG files which live in /usr/share/recoll/images.

    -
  • -
  • Under the [categories] section, you should add the MIME type -where it makes sense (you can also create a category). Categories may -be used for filtering in advanced search.

    -
  • -
-

The rclblob handler should be an executable program or script which -exists inside /usr/share/recoll/filters. It will be given a file -name as argument and should output the text or html contents on the -standard output.

-

The filter programming section describes in -more detail how to write an input handler.

-
-
-
-
-
- - -
-
-
- -
-
- - - - - - - \ No newline at end of file diff --git a/src/doc/user/sphinx/_build/html/usermanual.html b/src/doc/user/sphinx/_build/html/usermanual.html deleted file mode 100644 index 9a8e97bb..00000000 --- a/src/doc/user/sphinx/_build/html/usermanual.html +++ /dev/null @@ -1,5364 +0,0 @@ - - - - - - - - Recoll user manual — recoll 1.25.12 documentation - - - - - - - - - - - - - - - - - - - - -
-
-
-
- -
-

Recoll user manual

- --- - - - -
Author:Jean-Francois Dockes
- -
-

Introduction

-

This document introduces full text search notions and describes the -installation and use of the RCL application. It is updated for RCL -RCLVERSION.

-

RCL was for a long time dedicated to Unix-like systems. It was only -lately (2015) ported to MS-Windows. Many references in this manual, -especially file locations, are specific to Unix, and not valid on WIN, -where some described features are also not available. The manual will be -progressively updated. Until this happens, on WIN, most references to -shared files can be translated by looking under the Recoll installation -directory (esp. the Share subdirectory). The user configuration is -stored by default under AppData/Local/Recoll inside the user -directory, along with the index itself.

-
-

Giving it a try

-

If you do not like reading manuals (who does?) but wish to give RCL a -try, just install the application and start -the recoll graphical user interface (GUI), which will ask permission -to index your home directory by default, allowing you to search -immediately after indexing completes.

-

Do not do this if your home directory contains a huge number of -documents and you do not want to wait or are very short on disk space. -In this case, you may first want to customize the -configuration to restrict the indexed area -(for the very impatient with a completed package install, from the -recoll GUI: Preferences > Indexing configuration, then adjust the -Top directories section).

-

On Unix/Linux, you may need to install the appropriate supporting -applications for document types that need -them (for example antiword for Microsoft Word files).

-

The RCL for WIN package is self-contained and includes most useful -auxiliary programs. You will just need to install Python 2.7.

-
- -
-

Recoll overview

-

RCL uses the XAP information retrieval -library as its storage and retrieval engine. XAP is a very mature -package using a sophisticated probabilistic ranking -model.

-

The XAP library manages an index database which describes where terms -appear in your document files. It efficiently processes the complex -queries which are produced by the RCL query expansion mechanism, and is -in charge of the all-important relevance computation task.

-

RCL provides the mechanisms and interface to get data into and out of -the index. This includes translating the many possible document formats -into pure text, handling term variations (using XAP stemmers), and -spelling approximations (using the aspell speller), interpreting user -queries and presenting results.

-

In a shorter way, RCL does the dirty footwork, XAP deals with the -intelligent parts of the process.

-

The XAP index can be big (roughly the size of the original document -set), but it is not a document archive. RCL can only display documents -that still exist at the place from which they were indexed. (Actually, -there is a way to reconstruct a document from the information in the -index, but only the pure text is saved, possibly without punctuation and -capitalization, depending on RCL version).

-

RCL stores all internal data in Unicode UTF-8 format, and it can index -files of many types with different character sets, encodings, and -languages into the same index. It can process documents embedded inside -other documents (for example a pdf document stored inside a Zip archive -sent as an email attachment...), down to an arbitrary depth.

-

Stemming is the process by which RCL reduces words to their radicals so -that searching does not depend, for example, on a word being singular or -plural (floor, floors), or on a verb tense (flooring, floored). Because -the mechanisms used for stemming depend on the specific grammatical -rules for each language, there is a separate XAP stemmer module for most -common languages where stemming makes sense.

-

RCL stores the unstemmed versions of terms in the main index and uses -auxiliary databases for term expansion (one for each stemming language), -which means that you can switch stemming languages between searches, or -add a language without needing a full reindex.

-

Storing documents written in different languages in the same index is -possible, and commonly done. In this situation, you can specify several -stemming languages for the index.

-

RCL currently makes no attempt at automatic language recognition, which -means that the stemmer will sometimes be applied to terms from other -languages with potentially strange results. In practise, even if this -introduces possibilities of confusion, this approach has been proven -quite useful, and it is much less cumbersome than separating your -documents according to what language they are written in.

-

By default, RCL strips most accents and diacritics from terms, and -converts them to lower case before either storing them in the index or -searching for them. As a consequence, it is impossible to search for a -particular capitalization of a term (US / us), or to -discriminate two terms based on diacritics (sake / saké, -mate / maté).

-

RCL can optionally store the raw terms, without accent stripping or case -conversion. In this configuration, default searches will behave as -before, but it is possible to perform searches sensitive to case and -diacritics. This is described in more detail in the section about index -case and diacritics sensitivity.

-

RCL has many parameters which define exactly what to index, and how to -classify and decode the source documents. These are kept in -configuration files. A default configuration -is copied into a standard location (usually something like -/usr/share/recoll/examples) during installation. The default values -set by the configuration files in this directory may be overridden by -values set inside your personal configuration, found by default in the -.recoll sub-directory of your home directory. The default -configuration will index your home directory with default parameters and -should be sufficient for giving RCL a try, but you may want to adjust it -later, which can be done either by editing the text files or by using -configuration menus in the recoll GUI. Some other parameters -affecting only the recoll GUI are stored in the standard location -defined by Qt.

-

The indexing process is started -automatically (after asking permission), the first time you execute the -recoll GUI. Indexing can also be performed by executing the -recollindex command. RCL indexing is multithreaded by default when -appropriate hardware resources are available, and can perform in -parallel multiple tasks for text extraction, segmentation and index -updates.

-

Searches are usually performed inside the recoll -GUI, which has many options to help you find what you are looking for. -However, there are other ways to perform RCL searches:

- -
-
-
-

Indexing

-
-

Introduction

-

Indexing is the process by which the set of documents is analyzed and -the data entered into the database. RCL indexing is normally -incremental: documents will only be processed if they have been modified -since the last run. On the first execution, all documents will need -processing. A full index build can be forced later by specifying an -option to the indexing command (recollindex -z or -Z).

-

recollindex skips files which caused an error during a previous -pass. This is a performance optimization, and a new behaviour in version -1.21 (failed files were always retried by previous versions). The -command line option -k can be set to retry failed files, for example -after updating an input handler.

-

The following sections give an overview of different aspects of the -indexing processes and configuration, with links to detailed sections.

-

Depending on your data, temporary files may be needed during indexing, -some of them possibly quite big. You can use the RECOLL_TMPDIR or -TMPDIR environment variables to determine where they are created (the -default is to use /tmp). Using TMPDIR has the nice property that it -may also be taken into account by auxiliary commands executed by -recollindex.

-
-

Indexing modes

-

RCL indexing can be performed along two main modes:

-
    -
  • `Periodic (or batch) indexing: <#RCL.INDEXING.PERIODIC>`__.

    -

    recollindex is executed at discrete times. The typical usage is -to have a nightly run programmed -into your cron file.

    -
  • -
  • `Real time indexing: <#RCL.INDEXING.MONITOR>`__.

    -

    recollindex runs permanently as a daemon and uses a file system -alteration monitor (e.g. inotify) to detect file changes. New or -updated files are indexed at once.

    -
  • -
-

The choice between the two methods is mostly a matter of preference, and -they can be combined by setting up multiple indexes (ie: use periodic -indexing on a big documentation directory, and real time indexing on a -small home directory). Monitoring a big file system tree can consume -significant system resources.

-

With RCL 1.24 and newer, it is also possible to set up an index so that -only a subset of the tree will be monitored and the rest will be covered -by batch/incremental indexing. (See the details in the Real time -indexing section.

-

The choice of method and the parameters used can be configured from the -recoll GUI: Preferences > Indexing schedule

-

The GUI File menu also has entries to start or stop the current indexing -operation. Stopping indexing is performed by killing the recollindex -process, which will checkpoint its state and exit. A later restart of -indexing will mostly resume from where things stopped (the file tree -walk has to be restarted from the beginning).

-

When the real time indexer is running, two operations are available from -the menu: ‘Stop’ and ‘Trigger incremental pass’. When no indexing is -running, you have a choice of updating the index or rebuilding it (the -first choice only processes changed files, the second one zeroes the -index before starting so that all files are processed).

-
-
-

Configurations, multiple indexes

-

RCL supports defining multiple indexes, each defined by its own -configuration directory, in which several -configuration files describe what should be indexed and how.

-

A default personal configuration directory ($HOME/.recoll/) is -created when a RCL program is first executed. This configuration is the -one used for indexing and querying when no specific configuration is -specified.

-

All configuration parameters have defaults, defined in system-wide -files. Without further customisation, the default configuration will -process your complete home directory, with a reasonable set of defaults. -It can be changed to process a different area of the file system, select -files in different ways, and many other things.

-

In some cases, it may be useful to create additional configuration -directories, for example, to separate personal and shared indexes, or to -take advantage of the organization of your data to improve search -precision.

-

A plausible usage scenario for the multiple index feature would be for a -system administrator to set up a central index for shared data, that you -choose to search or not in addition to your personal data. Of course, -there are other possibilities. for example, there are many cases where -you know the subset of files that should be searched, and where -narrowing the search can improve the results. You can achieve -approximately the same effect with the directory filter in advanced -search, but multiple indexes may have better performance and may be -worth the trouble in some cases.

-

A more advanced use case would be to use multiple index to improve -indexing performance, by updating several indexes in parallel (using -multiple CPU cores and disks, or possibly several machines), and then -merging them, or querying them in parallel.

-

A specific configuration can be selected by setting the RECOLL_CONFDIR -environment variable, or giving the -c option to any of the RCL -commands.

-

When creating or updating indexes, the different configurations are -entirely independant (no parameters are ever shared between -configurations when indexing). The recollindex program always works -on a single index.

-

When querying, multiple indexes can be accessed concurrently, either -from the GUI or the command line. When doing this, there is always one -main configuration, from which both configuration and index data are -used. Only the index data from the additional indexes is used (their -configuration parameters are ignored).

-

The behaviour of index update and query regarding multiple -configurations is important and sometimes confusing, so it will be -rephrased here: for index generation, multiple configurations are -totally independant from each other. When querying, configuration and -data are used from the main index (the one designated by -c or -RECOLL_CONFDIR), and only the data from the additional indexes is used. -This implies that some parameters should be consistent among the -configurations for indexes which are to be used together.

-

See the section about configuring multiple -indexes for more detail

-
-
-

Document types

-

RCL knows about quite a few different document types. The parameters for -document types recognition and processing are set in configuration -files.

-

Most file types, like HTML or word processing files, only hold one -document. Some file types, like email folders or zip archives, can hold -many individually indexed documents, which may themselves be compound -ones. Such hierarchies can go quite deep, and RCL can process, for -example, a LibreOffice document stored as an attachment to an email -message inside an email folder archived in a zip file...

-

recollindex processes plain text, HTML, OpenDocument -(Open/LibreOffice), email formats, and a few others internally.

-

Other file types (ie: postscript, pdf, ms-word, rtf ...) need external -applications for preprocessing. The list is in the -installation section. After every indexing -operation, RCL updates a list of commands that would be needed for -indexing existing files types. This list can be displayed by selecting -the menu option File > Show Missing Helpers in the recoll GUI. It is -stored in the missing text file inside the configuration directory.

-

By default, RCL will try to index any file type that it has a way to -read. This is sometimes not desirable, and there are ways to either -exclude some types, or on the contrary define a positive list of types -to be indexed. In the latter case, any type not in the list will be -ignored.

-

Excluding files by name can be done by adding wildcard name patterns to -the skippedNames list, -which can be done from the GUI Index configuration menu. Excluding by -type can be done by setting the -excludedmimetypes -list in the configuration file (1.20 and later). This can be redefined -for subdirectories.

-

You can also define an exclusive list of MIME types to be indexed (no -others will be indexed), by settting the -indexedmimetypes -configuration variable. Example:

-
indexedmimetypes = text/html application/pdf
-
-
-

It is possible to redefine this parameter for subdirectories. Example:

-
[/path/to/my/dir]
-indexedmimetypes = application/pdf
-
-
-

(When using sections like this, don’t forget that they remain in effect -until the end of the file or another section indicator).

-

excludedmimetypes or indexedmimetypes, can be set either by -editing the configuration file -(``recoll.conf`) <#RCL.INSTALL.CONFIG.RECOLLCONF>`__ for the index, or -by using the GUI index configuration tool.

-
-

Note

-

When editing the indexedmimetypes or excludedmimetypes -lists, you should use the MIME values listed in the mimemap file -or in Recoll result lists in preference to file -i output: there -are a number of differences. The file -i output should only be -used for files without extensions, or for which the extension is not -listed in mimemap

-
-
-
-

Indexing failures

-

Indexing may fail for some documents, for a number of reasons: a helper -program may be missing, the document may be corrupt, we may fail to -uncompress a file because no file system space is available, etc.

-

RCL versions prior to 1.21 always retried to index files which had -previously caused an error. This guaranteed that anything that may have -become indexable (for example because a helper had been installed) would -be indexed. However this was bad for performance because some indexing -failures may be quite costly (for example failing to uncompress a big -file because of insufficient disk space).

-

The indexer in RCL versions 1.21 and later does not retry failed files -by default. Retrying will only occur if an explicit option (-k) is -set on the recollindex command line, or if a script executed when -recollindex starts up says so. The script is defined by a -configuration variable (checkneedretryindexscript), and makes a -rather lame attempt at deciding if a helper command may have been -installed, by checking if any of the common bin directories have -changed.

-
-
-

Recovery

-

In the rare case where the index becomes corrupted (which can signal -itself by weird search results or crashes), the index files need to be -erased before restarting a clean indexing pass. Just delete the -xapiandb directory (see next section), -or, alternatively, start the next recollindex with the -z -option, which will reset the database before indexing. The difference -between the two methods is that the second will not change the current -index format, which may be undesirable if a newer format is supported by -the XAP version.

-
-
-
-

Index storage

-

The default location for the index data is the xapiandb subdirectory -of the RCL configuration directory, typically -$HOME/.recoll/xapiandb/. This can be changed via two different -methods (with different purposes):

-
    -
  1. For a given configuration directory, you can specify a non-default -storage location for the index by setting the dbdir parameter in -the configuration file (see the configuration -section). This method would -mainly be of use if you wanted to keep the configuration directory in -its default location, but desired another location for the index, -typically out of disk occupation or performance concerns.

    -
  2. -
  3. You can specify a different configuration directory by setting the -RECOLL_CONFDIR environment variable, or using the -c option to -the RCL commands. This method would typically be used to index -different areas of the file system to different indexes. For example, -if you were to issue the following command:

    -
    recoll -c ~/.indexes-email
    -
    -
    -

    Then RCL would use configuration files stored in -~/.indexes-email/ and, (unless specified otherwise in -recoll.conf) would look for the index in -~/.indexes-email/xapiandb/.

    -

    Using multiple configuration directories and configuration -options allows you to tailor -multiple configurations and indexes to handle whatever subset of the -available data you wish to make searchable.

    -
  4. -
-

The size of the index is determined by the size of the set of documents, -but the ratio can vary a lot. For a typical mixed set of documents, the -index size will often be close to the data set size. In specific cases -(a set of compressed mbox files for example), the index can become much -bigger than the documents. It may also be much smaller if the documents -contain a lot of images or other non-indexed data (an extreme example -being a set of mp3 files where only the tags would be indexed).

-

Of course, images, sound and video do not increase the index size, which -means that in most cases, the space used by the index will be negligible -against the total amount of data on the computer.

-

The index data directory (xapiandb) only contains data that can be -completely rebuilt by an index run (as long as the original documents -exist), and it can always be destroyed safely.

-
-

XAP index formats

-

XAP versions usually support several formats for index storage. A given -major XAP version will have a current format, used to create new -indexes, and will also support the format from the previous major -version.

-

XAP will not convert automatically an existing index from the older -format to the newer one. If you want to upgrade to the new format, or if -a very old index needs to be converted because its format is not -supported any more, you will have to explicitly delete the old index -(typically ~/.recoll/xapiandb), then run a normal indexing command. -Using recollindex option -z would not work in this situation.

-
-
-

Security aspects

-

The RCL index does not hold complete copies of the indexed documents (it -almost does after version 1.24). But it does hold enough data to allow -for an almost complete reconstruction. If confidential data is indexed, -access to the database directory should be restricted.

-

RCL will create the configuration directory with a mode of 0700 (access -by owner only). As the index data directory is by default a -sub-directory of the configuration directory, this should result in -appropriate protection.

-

If you use another setup, you should think of the kind of protection you -need for your index, set the directory and files access modes -appropriately, and also maybe adjust the umask used during index -updates.

-
-
-

Special considerations for big indexes

-

This only needs concern you if your index is going to be bigger than -around 5 GBytes. Beyond 10 GBytes, it becomes a serious issue. Most -people have much smaller indexes. For reference, 5 GBytes would be -around 2000 bibles, a lot of text. If you have a huge text dataset -(remember: images don’t count, the text content of PDFs is typically -less than 5% of the file size), read on.

-

The amount of writing performed by Xapian during index creation is not -linear with the index size (it is somewhere between linear and -quadratic). For big indexes this becomes a performance issue, and may -even be an SSD disk wear issue.

-

The problem can be mitigated by observing the following rules:

-
    -
  • Partition the data set and create several indexes of reasonable size -rather than a huge one. These indexes can then be queried in parallel -(using the RCL external indexes facility), or merged using -xapian-compact.
  • -
  • Have a lot of RAM available and set the idxflushmb RCL -configuration parameter as high as you can without swapping -(experimentation will be needed). 200 would be a minimum in this -context.
  • -
  • Use Xapian 1.4.10 or newer, as this version brought a significant -improvement in the amount of writes.
  • -
-
-
-
-

Index configuration

-

Variables set inside the RCL configuration -files control which areas of the file system -are indexed, and how files are processed. These variables can be set -either by editing the text files or by using the dialogs in the -``recoll` GUI <#RCL.INDEXING.CONFIG.GUI>`__.

-

The first time you start recoll, you will be asked whether or not -you would like it to build the index. If you want to adjust the -configuration before indexing, just click Cancel at this point, which -will get you into the configuration interface. If you exit at this -point, recoll will have created a ~/.recoll directory containing -empty configuration files, which you can edit by hand.

-

The configuration is documented inside the installation -chapter of this document, or in the recoll.conf -5 man page, but the most current information will most likely be the -comments inside the sample file. The most immediately useful variable is -probably `topdirs <#RCL.INSTALL.CONFIG.RECOLLCONF.TOPDIRS>`__, which -determines what subtrees and files get indexed.

-

The applications needed to index file types other than text, HTML or -email (ie: pdf, postscript, ms-word...) are described in the external -packages section.

-

As of Recoll 1.18 there are two incompatible types of Recoll indexes, -depending on the treatment of character case and diacritics. A further -section describes the two types in more -detail.

-
-

Multiple indexes

-

Multiple RCL indexes can be created by using several configuration -directories which are typically set to index different areas of the file -system. A specific index can be selected for updating or searching, -using the RECOLL_CONFDIR environment variable or the -c option to -recoll and recollindex.

-

Index configuration parameters can be set either by using a text editor -on the files, or, for most parameters, by using the recoll index -configuration GUI. In the latter case, the configuration directory for -which parameters are modified is the one which was selected by -RECOLL_CONFDIR or the -c parameter, and there is no way to switch -configurations within the GUI.

-

As a remainder from a previous section, a recollindex program -instance can only update one specific index, and it will only use -parameters from a single configuration (no parameters are ever shared -between configurations when indexing). All the query methods -(recoll, recollq, the Python API, etc.) operate with a main -configuration, from which both configuration and index data are used, -but can also query data from multiple additional indexes. Only the index -data from the latter is used, their configuration parameters are -ignored.

-

When searching, the current main index (defined by RECOLL_CONFDIR or --c) is always active. If this is undesirable, you can set up your -base configuration to index an empty directory.

-

If a set of multiple indexes are to be used together for searches, some -configuration parameters must be consistent among the set. These are -parameters which need to be the same when indexing and searching. As the -parameters come from the main configuration when searching, they need to -be compatible with what was set when creating the other indexes (which -came from their respective configuration directories).

-

Most importantly, all indexes to be queried concurrently must have the -same option concerning character case and diacritics stripping, but -there are other constraints. Most of the relevant parameters are -described in the linked -section.

-

The different search interfaces (GUI, command line, ...) have different -methods to define the set of indexes to be used, see the appropriate -section.

-

At the moment, using multiple configurations implies a small level of -command line usage. Additional configuration directories (beyond -~/.recoll) must be created by hand (mkdir or such), the GUI will -not do it. This is to avoid mistakenly creating additional directories -when an argument is mistyped. Also, the GUI or the indexer must be -launched with a specific option or environment to work on the right -configuration.

-

To be more practical, here follows a few examples of the commands need -to create, configure, update, and query an additional index.

-

Initially creating the configuration and index:

-
mkdir /path/to/my/new/config
-
-
-

Configuring the new index can be done from the recoll GUI, launched -from the command line to pass the -c option (you could create a -desktop file to do it for you), and then using the GUI index -configuration tool to set up the index.

-
recoll -c /path/to/my/new/config
-
-
-

Alternatively, you can just start a text editor on the main -configuration file `recoll.conf <#RCL.INSTALL.CONFIG.RECOLLCONF>`__.

-

Creating and updating the index can be done from the command line:

-
recollindex -c /path/to/my/new/config
-
-
-

or from the File menu of a GUI launched with the same option -(recoll, see above).

-

The same GUI would also let you set up batch indexing for the new index. -Real time indexing can only be set up from the GUI for the default index -(the menu entry will be inactive if the GUI was started with a -non-default -c option).

-

The new index can be queried alone with

-
recoll -c /path/to/my/new/config
-
-
-

Or, in parallel with the default index, by starting recoll without a --c option, and using the Preferences > External Index Dialog menu.

-
-
-

Index case and diacritics sensitivity

-

As of RCL version 1.18 you have a choice of building an index with terms -stripped of character case and diacritics, or one with raw terms. For a -source term of Résumé, the former will store resume, the latter -Résumé.

-

Each type of index allows performing searches insensitive to case and -diacritics: with a raw index, the user entry will be expanded to match -all case and diacritics variations present in the index. With a stripped -index, the search term will be stripped before searching.

-

A raw index allows for another possibility which a stripped index cannot -offer: using case and diacritics to discriminate between terms, -returning different results when searching for US and us or -resume and résumé. Read the section about search case and -diacritics sensitivity for more details.

-

The type of index to be created is controlled by the indexStripChars -configuration variable which can only be changed by editing the -configuration file. Any change implies an index reset (not automated by -RCL), and all indexes in a search must be set in the same way (again, -not checked by RCL).

-

If the indexStripChars is not set, RCL 1.18 creates a stripped index -by default, for compatibility with previous versions.

-

As a cost for added capability, a raw index will be slightly bigger than -a stripped one (around 10%). Also, searches will be more complex, so -probably slightly slower, and the feature is still young, so that a -certain amount of weirdness cannot be excluded.

-

One of the most adverse consequence of using a raw index is that some -phrase and proximity searches may become impossible: because each term -needs to be expanded, and all combinations searched for, the -multiplicative expansion may become unmanageable.

-
-
-

Indexing threads configuration

-

The RCL indexing process recollindex can use multiple threads to -speed up indexing on multiprocessor systems. The work done to index -files is divided in several stages and some of the stages can be -executed by multiple threads. The stages are:

-
    -
  1. File system walking: this is always performed by the main thread.
  2. -
  3. File conversion and data extraction.
  4. -
  5. Text processing (splitting, stemming, etc.).
  6. -
  7. XAP index update.
  8. -
-

You can also read a longer -document -about the transformation of RCL indexing to multithreading.

-

The threads configuration is controlled by two configuration file -parameters.

-
-
thrQSizes
-
This variable defines the job input queues configuration. There are -three possible queues for stages 2, 3 and 4, and this parameter -should give the queue depth for each stage (three integer values). -If a value of -1 is used for a given stage, no queue is used, and -the thread will go on performing the next stage. In practise, deep -queues have not been shown to increase performance. A value of 0 for -the first queue tells RCL to perform autoconfiguration (no need for -anything else in this case, thrTCounts is not used) - this is the -default configuration.
-
thrTCounts
-

This defines the number of threads used for each stage. If a value -of -1 is used for one of the queue depths, the corresponding thread -count is ignored. It makes no sense to use a value other than 1 for -the last stage because updating the XAP index is necessarily -single-threaded (and protected by a mutex).

-

Note

-

If the first value in thrQSizes is 0, thrTCounts is ignored.

-
-
-

The following example would use three queues (of depth 2), and 4 threads -for converting source documents, 2 for processing their text, and one to -update the index. This was tested to be the best configuration on the -test system (quadri-processor with multiple disks).

-
thrQSizes = 2 2 2
-thrTCounts =  4 2 1
-
-
-

The following example would use a single queue, and the complete -processing for each document would be performed by a single thread -(several documents will still be processed in parallel in most cases). -The threads will use mutual exclusion when entering the index update -stage. In practise the performance would be close to the precedent case -in general, but worse in certain cases (e.g. a Zip archive would be -performed purely sequentially), so the previous approach is preferred. -YMMV... The 2 last values for thrTCounts are ignored.

-
thrQSizes = 2 -1 -1
-thrTCounts =  6 1 1
-
-
-

The following example would disable multithreading. Indexing will be -performed by a single thread.

-
thrQSizes = -1 -1 -1
-
-
-
-
-

The index configuration GUI

-

Most parameters for a given index configuration can be set from a -recoll GUI running on this configuration (either as default, or by -setting RECOLL_CONFDIR or the -c option.)

-

The interface is started from the Preferences > Index Configuration menu -entry. It is divided in four tabs, Global parameters, Local parameters, -Web history (which is explained in the next section) and Search -parameters.

-

The Global parameters tab allows setting global variables, like the -lists of top directories, skipped paths, or stemming languages.

-

The Local parameters tab allows setting variables that can be redefined -for subdirectories. This second tab has an initially empty list of -customisation directories, to which you can add. The variables are then -set for the currently selected directory (or at the top level if the -empty line is selected).

-

The Search parameters section defines parameters which are used at query -time, but are global to an index and affect all search tools, not only -the GUI.

-

The meaning for most entries in the interface is self-evident and -documented by a ToolTip popup on the text label. For more detail, -you will need to refer to the configuration -section of this guide.

-

The configuration tool normally respects the comments and most of the -formatting inside the configuration file, so that it is quite possible -to use it on hand-edited files, which you might nevertheless want to -backup first...

-
-
-
-

Indexing the WEB pages which you wisit.

-

With the help of a Firefox extension, RCL can index the Internet pages -that you visit. The extension has a long history: it was initially -designed for the Beagle indexer, then adapted to RCL and the Firefox XUL -API. A new version of the addon has been written to work with the -WebExtensions API, which is the only one supported after Firefox version -57.

-

The extension works by copying visited WEB pages to an indexing queue -directory, which RCL then processes, indexing the data, storing it into -a local cache, then removing the file from the queue.

-

Because the WebExtensions API introduces more constraints to what -extensions can do, the new version works with one more step: the files -are first created in the browser default downloads location (typically -$HOME/Downloads ), then moved by a script in the old queue location. -The script is automatically executed by the RCL indexer versions 1.23.5 -and newer. It could conceivably be executed independantly to make the -new browser extension compatible with an older RCL version (the script -is named recoll-we-move-files.py).

-
-

Note

-

For the WebExtensions-based version to work, it is necessary to set -the webdownloadsdir value in the configuration if it was changed -from the default $HOME/Downloads in the browser preferences.

-
-

The visited WEB pages indexing feature can be enabled on the RCL side -from the GUI Index configuration panel, or by editing the configuration -file (set processwebqueue to 1).

-

A current pointer to the extension can be found, along with up-to-date -instructions, on the Recoll wiki.

-

A copy of the indexed WEB pages is retained by Recoll in a local cache -(from which previews can be fetched). The cache size can be adjusted -from the Index configuration / Web history panel. Once the maximum size -is reached, old pages are purged - both from the cache and the index - -to make room for new ones, so you need to explicitly archive in some -other place the pages that you want to keep indefinitely.

-
-
-

Extended attributes data

-

User extended attributes are named pieces of information that most -modern file systems can attach to any file.

-

RCL versions 1.19 and later process extended attributes as document -fields by default. For older versions, this has to be activated at build -time.

-

A freedesktop -standard -defines a few special attributes, which are handled as such by RCL:

-
-
mime_type
-
If set, this overrides any other determination of the file MIME -type.
-
charset
-
If set, this defines the file character set (mostly useful for plain -text files).
-
-

By default, other attributes are handled as RCL fields. On Linux, the -user prefix is removed from the name. This can be configured more -precisely inside the `fields configuration -file <#RCL.INSTALL.CONFIG.FIELDS>`__.

-
-
-

Importing external tags

-

During indexing, it is possible to import metadata for each file by -executing commands. For example, this could extract user tag data for -the file and store it in a field for indexing.

-

See the section about the ``metadatacmds` -field <#RCL.INSTALL.CONFIG.RECOLLCONF.METADATACMDS>`__ in the main -configuration chapter for a description of the configuration syntax.

-

As an example, if you would want RCL to use tags managed by tmsu, you -would add the following to the configuration file:

-
[/some/area/of/the/fs]
-      metadatacmds = ; tags = tmsu tags %f
-
-
-**Note**
-
-Depending on the tmsu version, you may need/want to add options like
-``--database=/some/db``.
-
-
-

You may want to restrict this processing to a subset of the directory -tree, because it may slow down indexing a bit -([some/area/of/the/fs]).

-

Note the initial semi-colon after the equal sign.

-

In the example above, the output of tmsu is used to set a field -named tags. The field name is arbitrary and could be tmsu or -myfield just the same, but tags is an alias for the standard RCL -keywords field, and the tmsu output will just augment its -contents. This will avoid the need to extend the field -configuration.

-

Once re-indexing is performed (you’ll need to force the file reindexing, -RCL will not detect the need by itself), you will be able to search from -the query language, through any of its aliases: -tags:some/alternate/values or tags:all,these,values (the compact -field search syntax is supported for recoll 1.20 and later. For older -versions, you would need to repeat the tags: specifier for each -term, e.g. tags:some OR tags:alternate).

-

You should be aware that tags changes will not be detected by the -indexer if the file itself did not change. One possible workaround would -be to update the file ctime when you modify the tags, which would be -consistent with how extended attributes function. A pair of chmod -commands could accomplish this, or a touch -a . Alternatively, just -couple the tag update with a recollindex -e -i filename.

-
-
-

The PDF input handler

-

The PDF format is very important for scientific and technical -documentation, and document archival. It has extensive facilities for -storing metadata along with the document, and these facilities are -actually used in the real world.

-

In consequence, the rclpdf.py PDF input handler has more complex -capabilities than most others, and it is also more configurable. -Specifically, rclpdf.py can automatically use tesseract to perform -OCR if the document text is empty, it can be configured to extract -specific metadata tags from an XMP packet, and to extract PDF -attachments.

-
-

OCR with Tesseract

-

If both tesseract and pdftoppm (generally from the poppler-utils -package) are installed, the PDF handler may attempt OCR on PDF files -with no text content. This is controlled by the -pdfocr configuration -variable, which is false by default because OCR is very slow.

-

The choice of language is very important for successfull OCR. Recoll has -currently no way to determine this from the document itself. You can set -the language to use through the contents of a .ocrpdflang text file -in the same directory as the PDF document, or through the -RECOLL_TESSERACT_LANG environment variable, or through the contents of -an ocrpdf text file inside the configuration directory. If none of -the above are used, RCL will try to guess the language from the NLS -environment.

-
-
-

XMP fields extraction

-

The rclpdf.py script in RCL version 1.23.2 and later can extract XMP -metadata fields by executing the pdfinfo command (usually found with -poppler-utils). This is controlled by the -pdfextrameta -configuration variable, which specifies which tags to extract and, -possibly, how to rename them.

-

The pdfextrametafix -variable can be used to designate a file with Python code to edit the -metadata fields (available for RCL 1.23.3 and later. 1.23.2 has -equivalent code inside the handler script). Example:

-
import sys
-        import re
-
-        class MetaFixer(object):
-        def __init__(self):
-        pass
-
-        def metafix(self, nm, txt):
-        if nm == 'bibtex:pages':
-        txt = re.sub(r'--', '-', txt)
-        elif nm == 'someothername':
-        # do something else
-        pass
-        elif nm == 'stillanother':
-        # etc.
-        pass
-
-        return txt
-        def wrapup(self, metaheaders):
-        pass
-
-
-

If the ‘metafix()’ method is defined, it is called for each metadata -field. A new MetaFixer object is created for each PDF document (so the -object can keep state for, for example, eliminating duplicate values). -If the ‘wrapup()’ method is defined, it is called at the end of XMP -fields processing with the whole metadata as parameter, as an array of -‘(nm, val)’ pairs, allowing an alternate approach for editing or -adding/deleting fields.

-
-
-

PDF attachment indexing

-

If pdftk is installed, and if the the -pdfattach configuration -variable is set, the PDF input handler will try to extract PDF -attachements for indexing as sub-documents of the PDF file. This is -disabled by default, because it slows down PDF indexing a bit even if -not one attachment is ever found (PDF attachments are uncommon in my -experience).

-
-
-
-

Periodic indexing

-
-

Running indexing

-

Indexing is always performed by the recollindex program, which can -be started either from the command line or from the File menu in the -recoll GUI program. When started from the GUI, the indexing will run -on the same configuration recoll was started on. When started from -the command line, recollindex will use the RECOLL_CONFDIR variable -or accept a -c confdir option to specify a non-default configuration -directory.

-

If the recoll program finds no index when it starts, it will -automatically start indexing (except if canceled).

-

The recollindex indexing process can be interrupted by sending an -interrupt (Ctrl-C, SIGINT) or terminate (SIGTERM) signal. Some time may -elapse before the process exits, because it needs to properly flush and -close the index. This can also be done from the recoll GUI File > -Stop Indexing menu entry.

-

After such an interruption, the index will be somewhat inconsistent -because some operations which are normally performed at the end of the -indexing pass will have been skipped (for example, the stemming and -spelling databases will be inexistant or out of date). You just need to -restart indexing at a later time to restore consistency. The indexing -will restart at the interruption point (the full file tree will be -traversed, but files that were indexed up to the interruption and for -which the index is still up to date will not need to be reindexed).

-

recollindex has a number of other options which are described in its -man page. Only a few will be described here.

-

Option -z will reset the index when starting. This is almost the -same as destroying the index files (the nuance is that the XAP format -version will not be changed).

-

Option -Z will force the update of all documents without resetting -the index first. This will not have the “clean start” aspect of -z, -but the advantage is that the index will remain available for querying -while it is rebuilt, which can be a significant advantage if it is very -big (some installations need days for a full index rebuild).

-

Option -k will force retrying files which previously failed to be -indexed, for example because of a missing helper program.

-

Of special interest also, maybe, are the -i and -f options. --i allows indexing an explicit list of files (given as command line -parameters or read on stdin). -f tells recollindex to ignore -file selection parameters from the configuration. Together, these -options allow building a custom file selection process for some area of -the file system, by adding the top directory to the skippedPaths -list and using an appropriate file selection method to build the file -list to be fed to recollindex -if. Trivial example:

-
find . -name indexable.txt -print | recollindex -if
-
-
-

recollindex -i will not descend into subdirectories specified as -parameters, but just add them as index entries. It is up to the external -file selection method to build the complete file list.

-
-
-

Using cron to automate indexing

-

The most common way to set up indexing is to have a cron task execute it -every night. For example the following crontab entry would do it -every day at 3:30AM (supposing recollindex is in your PATH):

-
30 3 * * * recollindex > /some/tmp/dir/recolltrace 2>&1
-
-
-

Or, using anacron:

-
1  15  su mylogin -c "recollindex recollindex > /tmp/rcltraceme 2>&1"
-
-
-

As of version 1.17 the RCL GUI has dialogs to manage crontab entries -for recollindex. You can reach them from the Preferences > Indexing -Schedule menu. They only work with the good old cron, and do not -give access to all features of cron scheduling.

-

The usual command to edit your crontab is crontab -e (which -will usually start the vi editor to edit the file). You may have -more sophisticated tools available on your system.

-

Please be aware that there may be differences between your usual -interactive command line environment and the one seen by crontab -commands. Especially the PATH variable may be of concern. Please check -the crontab manual pages about possible issues.

-
-
-
-

Real time indexing

-

Real time monitoring/indexing is performed by starting the -recollindex -m command. With this option, recollindex will -detach from the terminal and become a daemon, permanently monitoring -file changes and updating the index.

-

While it is convenient that data is indexed in real time, repeated -indexing can generate a significant load on the system when files such -as email folders change. Also, monitoring large file trees by itself -significantly taxes system resources. You probably do not want to enable -it if your system is short on resources. Periodic indexing is adequate -in most cases.

-

As of RCL 1.24, you can set the -monitordirs -configuration variable to specify that only a subset of your indexed -files will be monitored for instant indexing. In this situation, an -incremental pass on the full tree can be triggered by either restarting -the indexer, or just running recollindex, which will notify the -running process. The recoll GUI also has a menu entry for this.

-
-

Real time indexing: automatic daemon start

-

Under KDE, Gnome and some other desktop environments, the daemon can -automatically started when you log in, by creating a desktop file inside -the ~/.config/autostart directory. This can be done for you by the -RCL GUI. Use the Preferences->Indexing Schedule menu.

-

With older X11 setups, starting the daemon is normally performed as part -of the user session script.

-

The rclmon.sh script can be used to easily start and stop the -daemon. It can be found in the examples directory (typically -/usr/local/[share/]recoll/examples).

-

For example, my out of fashion xdm-based session has a .xsession -script with the following lines at the end:

-
recollconf=$HOME/.recoll-home
-        recolldata=/usr/local/share/recoll
-        RECOLL_CONFDIR=$recollconf $recolldata/examples/rclmon.sh start
-
-        fvwm
-
-
-

The indexing daemon gets started, then the window manager, for which the -session waits.

-

By default the indexing daemon will monitor the state of the X11 -session, and exit when it finishes, it is not necessary to kill it -explicitly. (The X11 server monitoring can be disabled with option --x to recollindex).

-

If you use the daemon completely out of an X11 session, you need to add -option -x to disable X11 session monitoring (else the daemon will -not start).

-
-
-

Real time indexing: miscellaneous details

-

By default, the messages from the indexing daemon will be sent to the -same file as those from the interactive commands (logfilename). You -may want to change this by setting the daemlogfilename and -daemloglevel configuration parameters. Also the log file will only -be truncated when the daemon starts. If the daemon runs permanently, the -log file may grow quite big, depending on the log level.

-

When building RCL, the real time indexing support can be customised -during package configuration with the ---with[out]-fam or --with[out]-inotify options. The default is -currently to include inotify monitoring on systems that support it, and, -as of RCL 1.17, gamin support on FreeBSD.

-
-

Note

-

On Linux systems, monitoring a big tree may need increasing the -resources available to inotify, which are normally defined in -/etc/sysctl.conf.

-
### inotify
-#
-# cat  /proc/sys/fs/inotify/max_queued_events   - 16384
-# cat  /proc/sys/fs/inotify/max_user_instances  - 128
-# cat  /proc/sys/fs/inotify/max_user_watches    - 16384
-#
-# -- Change to:
-#
-fs.inotify.max_queued_events=32768
-fs.inotify.max_user_instances=256
-fs.inotify.max_user_watches=32768
-
-
-

Especially, you will need to trim your tree or adjust the -max_user_watches value if indexing exits with a message about -errno ENOSPC (28) from inotify_add_watch.

-

Note

-

When using the real time monitor, it may happen that some files need -to be indexed, but change so often that they impose an excessive -load for the system.

-

RCL provides a configuration option to specify the minimum time -before which a file, specified by a wildcard pattern, cannot be -reindexed. See the mondelaypatterns parameter in the -configuration section.

-
-
-
-
-
-

Searching

-
-

Searching with the Qt graphical user interface

-

The recoll program provides the main user interface for searching. -It is based on the Qt library.

-

recoll has two search modes:

-
    -
  • Simple search (the default, on the main screen) has a single entry -field where you can enter multiple words.
  • -
  • Advanced search (a panel accessed through the Tools menu or the -toolbox bar icon) has multiple entry fields, which you may use to -build a logical condition, with additional filtering on file type, -location in the file system, modification date, and size.
  • -
-

In most cases, you can enter the terms as you think them, even if they -contain embedded punctuation or other non-textual characters. For -example, RCL can handle things like email addresses, or arbitrary cut -and paste from another text window, punctation and all.

-

The main case where you should enter text differently from how it is -printed is for east-asian languages (Chinese, Japanese, Korean). Words -composed of single or multiple characters should be entered separated by -white space in this case (they would typically be printed without white -space).

-

Some searches can be quite complex, and you may want to re-use them -later, perhaps with some tweaking. RCL versions 1.21 and later can save -and restore searches, using XML files. See Saving and restoring -queries.

- -
-

The default result list

-

After starting a search, a list of results will instantly be displayed -in the main list window.

-

By default, the document list is presented in order of relevance (how -well the system estimates that the document matches the query). You can -sort the result by ascending or descending date by using the vertical -arrows in the toolbar.

-

Clicking on the Preview link for an entry will open an internal -preview window for the document. Further Preview clicks for the same -search will open tabs in the existing preview window. You can use -Shift+Click to force the creation of another preview window, which may -be useful to view the documents side by side. (You can also browse -successive results in a single preview window by typing -Shift+ArrowUp/Down in the window).

-

Clicking the Open link will start an external viewer for the -document. By default, RCL lets the desktop choose the appropriate -application for most document types (there is a short list of -exceptions, see further). If you prefer to completely customize the -choice of applications, you can uncheck the Use desktop preferences -option in the GUI preferences dialog, and click the Choose editor -applications button to adjust the predefined RCL choices. The tool -accepts multiple selections of MIME types (e.g. to set up the editor for -the dozens of office file types).

-

Even when Use desktop preferences is checked, there is a small list of -exceptions, for MIME types where the RCL choice should override the -desktop one. These are applications which are well integrated with RCL, -especially evince for viewing PDF and Postscript files because of its -support for opening the document at a specific page and passing a search -string as an argument. Of course, you can edit the list (in the GUI -preferences) if you would prefer to lose the functionality and use the -standard desktop tool.

-

You may also change the choice of applications by editing the -`mimeview <#RCL.INSTALL.CONFIG.MIMEVIEW>`__ configuration file if -you find this more convenient.

-

Each result entry also has a right-click menu with an Open With entry. -This lets you choose an application from the list of those which -registered with the desktop for the document MIME type.

-

The Preview and Open edit links may not be present for all -entries, meaning that RCL has no configured way to preview a given file -type (which was indexed by name only), or no configured external editor -for the file type. This can sometimes be adjusted simply by tweaking the -`mimemap <#RCL.INSTALL.CONFIG.MIMEMAP>`__ and -`mimeview <#RCL.INSTALL.CONFIG.MIMEVIEW>`__ configuration files (the -latter can be modified with the user preferences dialog).

-

The format of the result list entries is entirely configurable by using -the preference dialog to edit an HTML -fragment.

-

You can click on the Query details link at the top of the results -page to see the query actually performed, after stem expansion and other -processing.

-

Double-clicking on any word inside the result list or a preview window -will insert it into the simple search text.

-

The result list is divided into pages (the size of which you can change -in the preferences). Use the arrow buttons in the toolbar or the links -at the bottom of the page to browse the results.

-
-
No results: the spelling suggestions
-

When a search yields no result, and if the aspell dictionary is -configured, RCL will try to check for misspellings among the query -terms, and will propose lists of replacements. Clicking on one of the -suggestions will replace the word and restart the search. You can hold -any of the modifier keys (Ctrl, Shift, etc.) while clicking if you would -rather stay on the suggestion screen because several terms need -replacement.

-
-
-
The result list right-click menu
-

Apart from the preview and edit links, you can display a pop-up menu by -right-clicking over a paragraph in the result list. This menu has the -following entries:

-
    -
  • Preview
  • -
  • Open
  • -
  • Open With
  • -
  • Run Script
  • -
  • Copy File Name
  • -
  • Copy Url
  • -
  • Save to File
  • -
  • Find similar
  • -
  • Preview Parent document
  • -
  • Open Parent document
  • -
  • Open Snippets Window
  • -
-

The Preview and Open entries do the same thing as the corresponding -links.

-

Open With lets you open the document with one of the applications -claiming to be able to handle its MIME type (the information comes from -the .desktop files in /usr/share/applications).

-

Run Script allows starting an arbitrary command on the result file. It -will only appear for results which are top-level files. See -further for a more detailed description.

-

The Copy File Name and Copy Url copy the relevant data to the clipboard, -for later pasting.

-

Save to File allows saving the contents of a result document to a chosen -file. This entry will only appear if the document does not correspond to -an existing file, but is a subdocument inside such a file (ie: an email -attachment). It is especially useful to extract attachments with no -associated editor.

-

The Open/Preview Parent document entries allow working with the higher -level document (e.g. the email message an attachment comes from). RCL is -sometimes not totally accurate as to what it can or can’t do in this -area. For example the Parent entry will also appear for an email which -is part of an mbox folder file, but you can’t actually visualize the -mbox (there will be an error dialog if you try).

-

If the document is a top-level file, Open Parent will start the default -file manager on the enclosing filesystem directory.

-

The Find similar entry will select a number of relevant term from the -current document and enter them into the simple search field. You can -then start a simple search, with a good chance of finding documents -related to the current result. I can’t remember a single instance where -this function was actually useful to me...

-

The Open Snippets Window entry will only appear for documents which -support page breaks (typically PDF, Postscript, DVI). The snippets -window lists extracts from the document, taken around search terms -occurrences, along with the corresponding page number, as links which -can be used to start the native viewer on the appropriate page. If the -viewer supports it, its search function will also be primed with one of -the search terms.

-
-
-
-

The result table

-

In RCL 1.15 and newer, the results can be displayed in spreadsheet-like -fashion. You can switch to this presentation by clicking the table-like -icon in the toolbar (this is a toggle, click again to restore the list).

-

Clicking on the column headers will allow sorting by the values in the -column. You can click again to invert the order, and use the header -right-click menu to reset sorting to the default relevance order (you -can also use the sort-by-date arrows to do this).

-

Both the list and the table display the same underlying results. The -sort order set from the table is still active if you switch back to the -list mode. You can click twice on a date sort arrow to reset it from -there.

-

The header right-click menu allows adding or deleting columns. The -columns can be resized, and their order can be changed (by dragging). -All the changes are recorded when you quit recoll

-

Hovering over a table row will update the detail area at the bottom of -the window with the corresponding values. You can click the row to -freeze the display. The bottom area is equivalent to a result list -paragraph, with links for starting a preview or a native application, -and an equivalent right-click menu. Typing Esc (the Escape key) will -unfreeze the display.

-
-
-

Running arbitrary commands on result files (1.20 and later)

-

Apart from the Open and Open With operations, which allow starting an -application on a result document (or a temporary copy), based on its -MIME type, it is also possible to run arbitrary commands on results -which are top-level files, using the Run Script entry in the results -pop-up menu.

-

The commands which will appear in the Run Script submenu must be defined -by .desktop files inside the scripts subdirectory of the current -configuration directory.

-

Here follows an example of a .desktop file, which could be named for -example, ~/.recoll/scripts/myscript.desktop (the exact file name -inside the directory is irrelevant):

-
[Desktop Entry]
-Type=Application
-Name=MyFirstScript
-Exec=/home/me/bin/tryscript %F
-MimeType=*/*
-
-
-

The Name attribute defines the label which will appear inside the -Run Script menu. The Exec attribute defines the program to be run, -which does not need to actually be a script, of course. The MimeType -attribute is not used, but needs to exist.

-

The commands defined this way can also be used from links inside the -result paragraph.

-

As an example, it might make sense to write a script which would move -the document to the trash and purge it from the RCL index.

-
-
-

Displaying thumbnails

-

The default format for the result list entries and the detail area of -the result table display an icon for each result document. The icon is -either a generic one determined from the MIME type, or a thumbnail of -the document appearance. Thumbnails are only displayed if found in the -standard freedesktop location, where they would typically have been -created by a file manager.

-

Recoll has no capability to create thumbnails. A relatively simple trick -is to use the Open parent document/folder entry in the result list popup -menu. This should open a file manager window on the containing -directory, which should in turn create the thumbnails (depending on your -settings). Restarting the search should then display the thumbnails.

-

There are also some pointers about thumbnail -generation on the RCL wiki.

-
-
-

The preview window

-

The preview window opens when you first click a Preview link inside -the result list.

-

Subsequent preview requests for a given search open new tabs in the -existing window (except if you hold the Shift key while clicking which -will open a new window for side by side viewing).

-

Starting another search and requesting a preview will create a new -preview window. The old one stays open until you close it.

-

You can close a preview tab by typing Ctrl-W (Ctrl + W) in the window. -Closing the last tab for a window will also close the window.

-

Of course you can also close a preview window by using the window -manager button in the top of the frame.

-

You can display successive or previous documents from the result list -inside a preview tab by typing Shift+Down or Shift+Up (Down and Up are -the arrow keys).

-

A right-click menu in the text area allows switching between displaying -the main text or the contents of fields associated to the document (ie: -author, abtract, etc.). This is especially useful in cases where the -term match did not occur in the main text but in one of the fields. In -the case of images, you can switch between three displays: the image -itself, the image metadata as extracted by exiftool and the fields, -which is the metadata stored in the index.

-

You can print the current preview window contents by typing Ctrl-P (Ctrl -+ P) in the window text.

-
-
Searching inside the preview
-

The preview window has an internal search capability, mostly controlled -by the panel at the bottom of the window, which works in two modes: as a -classical editor incremental search, where we look for the text entered -in the entry zone, or as a way to walk the matches between the document -and the RCL query that found it.

-
-
Incremental text search
-

The preview tabs have an internal incremental search function. You -initiate the search either by typing a / (slash) or CTL-F inside the -text area or by clicking into the Search for: text field and -entering the search string. You can then use the Next and Previous -buttons to find the next/previous occurrence. You can also type F3 -inside the text area to get to the next occurrence.

-

If you have a search string entered and you use Ctrl-Up/Ctrl-Down to -browse the results, the search is initiated for each successive -document. If the string is found, the cursor will be positioned at -the first occurrence of the search string.

-
-
Walking the match lists
-
If the entry area is empty when you click the Next or Previous -buttons, the editor will be scrolled to show the next match to any -search term (the next highlighted zone). If you select a search -group from the dropdown list and click Next or Previous, the match -list for this group will be walked. This is not the same as a text -search, because the occurences will include non-exact matches (as -caused by stemming or wildcards). The search will revert to the text -mode as soon as you edit the entry area.
-
-
-
-
-

The Query Fragments window

-

Selecting the Tools > Query Fragments menu entry will open a window with -radio- and check-buttons which can be used to activate query language -fragments for filtering the current query. This can be useful if you -have frequent reusable selectors, for example, filtering on alternate -directories, or searching just one category of files, not covered by the -standard category selectors.

-

The contents of the window are entirely customizable, and defined by the -contents of the fragbuts.xml file inside the configuration -directory. The sample file distributed with RCL (which you should be -able to find under /usr/share/recoll/examples/fragbuts.xml), -contains an example which filters the results from the WEB history.

-

Here follows an example:

-
<?xml version="1.0" encoding="UTF-8"?>
-
-<fragbuts version="1.0">
-
-<radiobuttons>
-
-<fragbut>
-<label>Include Web Results</label>
-<frag></frag>
-</fragbut>
-
-<fragbut>
-<label>Exclude Web Results</label>
-<frag>-rclbes:BGL</frag>
-</fragbut>
-
-<fragbut>
-<label>Only Web Results</label>
-<frag>rclbes:BGL</frag>
-</fragbut>
-
-</radiobuttons>
-
-<buttons>
-
-<fragbut>
-<label>Year 2010</label>
-<frag>date:2010-01-01/2010-12-31</frag>
-</fragbut>
-
-<fragbut>
-<label>My Great Directory Only</label>
-<frag>dir:/my/great/directory</frag>
-</fragbut>
-
-</buttons>
-</fragbuts>
-
-
-

Each radiobuttons or buttons section defines a line of -checkbuttons or radiobuttons inside the window. Any number of buttons -can be selected, but the radiobuttons in a line are exclusive.

-

Each fragbut section defines the label for a button, and the Query -Language fragment which will be added (as an AND filter) before -performing the query if the button is active.

-

This feature is new in RCL 1.20, and will probably be refined depending -on user feedback.

-
- -
-

The term explorer tool

-

RCL automatically manages the expansion of search terms to their -derivatives (ie: plural/singular, verb inflections). But there are other -cases where the exact search term is not known. For example, you may not -remember the exact spelling, or only know the beginning of the name.

-

The search will only propose replacement terms with spelling variations -when no matching document were found. In some cases, both proper -spellings and mispellings are present in the index, and it may be -interesting to look for them explicitely.

-

The term explorer tool (started from the toolbar icon or from the Term -explorer entry of the Tools menu) can be used to search the full index -terms list. It has three modes of operations:

-
-
Wildcard
-
In this mode of operation, you can enter a search string with -shell-like wildcards (*, ?, []). ie: xapi* would display all index -terms beginning with xapi. (More about wildcards -here ).
-
Regular expression
-
This mode will accept a regular expression as input. Example: -word[0-9]+. The expression is implicitely anchored at the beginning. -Ie: press will match pression but not expression. You can use -.*press to match the latter, but be aware that this will cause a -full index term list scan, which can be quite long.
-
Stem expansion
-
This mode will perform the usual stem expansion normally done as -part user input processing. As such it is probably mostly useful to -demonstrate the process.
-
Spelling/Phonetic
-
In this mode, you enter the term as you think it is spelled, and RCL -will do its best to find index terms that sound like your entry. -This mode uses the Aspell spelling application, which must be -installed on your system for things to work (if your documents -contain non-ascii characters, RCL needs an aspell version newer than -0.60 for UTF-8 support). The language which is used to build the -dictionary out of the index terms (which is done at the end of an -indexing pass) is the one defined by your NLS environment. Weird -things will probably happen if languages are mixed up.
-
-

Note that in cases where RCL does not know the beginning of the string -to search for (ie a wildcard expression like *coll), the expansion can -take quite a long time because the full index term list will have to be -processed. The expansion is currently limited at 10000 results for -wildcards and regular expressions. It is possible to change the limit in -the configuration file.

-

Double-clicking on a term in the result list will insert it into the -simple search entry field. You can also cut/paste between the result -list and any entry field (the end of lines will be taken care of).

-
-
-

Multiple indexes

-

See the section describing the use of multiple -indexes for generalities. Only the -aspects concerning the recoll GUI are described here.

-

A recoll program instance is always associated with a specific -index, which is the one to be updated when requested from the File menu, -but it can use any number of RCL indexes for searching. The external -indexes can be selected through the external indexes tab in the -preferences dialog.

-

Index selection is performed in two phases. A set of all usable indexes -must first be defined, and then the subset of indexes to be used for -searching. These parameters are retained across program executions -(there are kept separately for each RCL configuration). The set of all -indexes is usually quite stable, while the active ones might typically -be adjusted quite frequently.

-

The main index (defined by RECOLL_CONFDIR) is always active. If this is -undesirable, you can set up your base configuration to index an empty -directory.

-

When adding a new index to the set, you can select either a RCL -configuration directory, or directly a XAP index directory. In the first -case, the XAP index directory will be obtained from the selected -configuration.

-

As building the set of all indexes can be a little tedious when done -through the user interface, you can use the RECOLL_EXTRA_DBS -environment variable to provide an initial set. This might typically be -set up by a system administrator so that every user does not have to do -it. The variable should define a colon-separated list of index -directories, ie:

-
export RECOLL_EXTRA_DBS=/some/place/xapiandb:/some/other/db
-
-
-

Another environment variable, RECOLL_ACTIVE_EXTRA_DBS allows adding -to the active list of indexes. This variable was suggested and -implemented by a RCL user. It is mostly useful if you use scripts to -mount external volumes with RCL indexes. By using RECOLL_EXTRA_DBS and -RECOLL_ACTIVE_EXTRA_DBS, you can add and activate the index for the -mounted volume when starting recoll.

-

RECOLL_ACTIVE_EXTRA_DBS is available for RCL versions 1.17.2 and -later. A change was made in the same update so that recoll will -automatically deactivate unreachable indexes when starting up.

-
-
-

Document history

-

Documents that you actually view (with the internal preview or an -external tool) are entered into the document history, which is -remembered.

-

You can display the history list by using the Tools/Doc History menu -entry.

-

You can erase the document history by using the Erase document history -entry in the File menu.

-
-
-

Sorting search results and collapsing duplicates

-

The documents in a result list are normally sorted in order of -relevance. It is possible to specify a different sort order, either by -using the vertical arrows in the GUI toolbox to sort by date, or -switching to the result table display and clicking on any header. The -sort order chosen inside the result table remains active if you switch -back to the result list, until you click one of the vertical arrows, -until both are unchecked (you are back to sort by relevance).

-

Sort parameters are remembered between program invocations, but result -sorting is normally always inactive when the program starts. It is -possible to keep the sorting activation state between program -invocations by checking the Remember sort activation state option in the -preferences.

-

It is also possible to hide duplicate entries inside the result list -(documents with the exact same contents as the displayed one). The test -of identity is based on an MD5 hash of the document container, not only -of the text contents (so that ie, a text document with an image added -will not be a duplicate of the text only). Duplicates hiding is -controlled by an entry in the GUI configuration dialog, and is off by -default.

-

As of release 1.19, when a result document does have undisplayed -duplicates, a Dups link will be shown with the result list entry. -Clicking the link will display the paths (URLs + ipaths) for the -duplicate entries.

-
-
-

Search tips, shortcuts

-
-
Terms and search expansion
-

Term completion.

-

Typing Esc Space in the simple search entry field while entering a word -will either complete the current word if its beginning matches a unique -term in the index, or open a window to propose a list of completions.

-

Picking up new terms from result or preview text.

-

Double-clicking on a word in the result list or in a preview window will -copy it to the simple search entry field.

-

Wildcards.

-

Wildcards can be used inside search terms in all forms of searches. -More about wildcards.

-

Automatic suffixes.

-

Words like odt or ods can be automatically turned into query -language ext:xxx clauses. This can be enabled in the Search -preferences panel in the GUI.

-

Disabling stem expansion.

-

Entering a capitalized word in any search field will prevent stem -expansion (no search for gardening if you enter Garden instead -of garden). This is the only case where character case should make a -difference for a RCL search. You can also disable stem expansion or -change the stemming language in the preferences.

-

Finding related documents.

-

Selecting the Find similar documents entry in the result list paragraph -right-click menu will select a set of “interesting” terms from the -current result, and insert them into the simple search entry field. You -can then possibly edit the list and start a search to find documents -which may be apparented to the current result.

-

File names.

-

File names are added as terms during indexing, and you can specify them -as ordinary terms in normal search fields (RCL used to index all -directories in the file path as terms. This has been abandoned as it did -not seem really useful). Alternatively, you can use the specific file -name search which will only look for file names, and may be faster -than the generic search especially when using wildcards.

-
-
-
Working with phrases and proximity
-

Phrases and Proximity searches.

-

A phrase can be looked for by enclosing it in double quotes. Example: -"user manual" will look only for occurrences of user immediately -followed by manual. You can use the This phrase field of the -advanced search dialog to the same effect. Phrases can be entered along -simple terms in all simple or advanced search entry fields (except This -exact phrase).

-

AutoPhrases.

-

This option can be set in the preferences dialog. If it is set, a phrase -will be automatically built and added to simple searches when looking -for Any terms. This will not change radically the results, but will -give a relevance boost to the results where the search terms appear as a -phrase. Ie: searching for virtual reality will still find all -documents where either virtual or reality or both appear, but -those which contain virtual reality should appear sooner in the -list.

-

Phrase searches can strongly slow down a query if most of the terms in -the phrase are common. This is why the autophrase option is off by -default for RCL versions before 1.17. As of version 1.17, autophrase -is on by default, but very common terms will be removed from the -constructed phrase. The removal threshold can be adjusted from the -search preferences.

-

Phrases and abbreviations.

-

As of RCL version 1.17, dotted abbreviations like I.B.M. are also -automatically indexed as a word without the dots: IBM. Searching for -the word inside a phrase (ie: "the IBM company") will only match the -dotted abrreviation if you increase the phrase slack (using the advanced -search panel control, or the o query language modifier). Literal -occurences of the word will be matched normally.

-
-
-
Others
-

Using fields.

-

You can use the query language and field -specifications to only search certain parts of documents. This can be -especially helpful with email, for example only searching emails from a -specific originator: search tips from:helpfulgui

-

Ajusting the result table columns.

-

When displaying results in table mode, you can use a right click on the -table headers to activate a pop-up menu which will let you adjust what -columns are displayed. You can drag the column headers to adjust their -order. You can click them to sort by the field displayed in the column. -You can also save the result list in CSV format.

-

Changing the GUI geometry.

-

It is possible to configure the GUI in wide form factor by dragging the -toolbars to one of the sides (their location is remembered between -sessions), and moving the category filters to a menu (can be set in the -Preferences > GUI configuration > User interface panel).

-

Query explanation.

-

You can get an exact description of what the query looked for, including -stem expansion, and Boolean operators used, by clicking on the result -list header.

-

Advanced search history.

-

As of RCL 1.18, you can display any of the last 100 complex searches -performed by using the up and down arrow keys while the advanced search -panel is active.

-

Browsing the result list inside a preview window.

-

Entering Shift-Down or Shift-Up (Shift + an arrow key) in a preview -window will display the next or the previous document from the result -list. Any secondary search currently active will be executed on the new -document.

-

Scrolling the result list from the keyboard.

-

You can use PageUp and PageDown to scroll the result list, Shift+Home to -go back to the first page. These work even while the focus is in the -search entry.

-

Result table: moving the focus to the table.

-

You can use Ctrl-r to move the focus from the search entry to the table, -and then use the arrow keys to change the current row. Ctrl-Shift-s -returns to the search.

-

Result table: open / preview.

-

With the focus in the result table, you can use Ctrl-o to open the -document from the current row, Ctrl-Shift-o to open the document and -close recoll, Ctrl-d to preview the document.

-

Editing a new search while the focus is not in the search entry.

-

You can use the Ctrl-Shift-S shortcut to return the cursor to the search -entry (and select the current search text), while the focus is anywhere -in the main window.

-

Forced opening of a preview window.

-

You can use Shift+Click on a result list Preview link to force the -creation of a preview window instead of a new tab in the existing one.

-

Closing previews.

-

Entering Ctrl-W in a tab will close it (and, for the last tab, close the -preview window). Entering Esc will close the preview window and all its -tabs.

-

Printing previews.

-

Entering Ctrl-P in a preview window will print the currently displayed -text.

-

Quitting.

-

Entering Ctrl-Q almost anywhere will close the application.

-
-
-
-

Saving and restoring queries (1.21 and later)

-

Both simple and advanced query dialogs save recent history, but the -amount is limited: old queries will eventually be forgotten. Also, -important queries may be difficult to find among others. This is why -both types of queries can also be explicitely saved to files, from the -GUI menus: File > Save last query / Load last query

-

The default location for saved queries is a subdirectory of the current -configuration directory, but saved queries are ordinary files and can be -written or moved anywhere.

-

Some of the saved query parameters are part of the preferences (e.g. -autophrase or the active external indexes), and may differ when the -query is loaded from the time it was saved. In this case, RCL will warn -of the differences, but will not change the user preferences.

-
-
-

Customizing the search interface

-

You can customize some aspects of the search interface by using the GUI -configuration entry in the Preferences menu.

-

There are several tabs in the dialog, dealing with the interface itself, -the parameters used for searching and returning results, and what -indexes are searched.

-

User interface parameters:.

-
    -
  • Highlight color for query terms: Terms from the user query are -highlighted in the result list samples and the preview window. The -color can be chosen here. Any Qt color string should work (ie -red, #ff0000). The default is blue.

    -
  • -
  • Style sheet: The name of a Qt style sheet text file which is applied -to the whole Recoll application on startup. The default value is -empty, but there is a skeleton style sheet (recoll.qss) inside -the /usr/share/recoll/examples directory. Using a style sheet, -you can change most recoll graphical parameters: colors, fonts, -etc. See the sample file for a few simple examples.

    -

    You should be aware that parameters (e.g.: the background color) set -inside the RCL GUI style sheet will override global system -preferences, with possible strange side effects: for example if you -set the foreground to a light color and the background to a dark one -in the desktop preferences, but only the background is set inside the -RCL style sheet, and it is light too, then text will appear -light-on-light inside the RCL GUI.

    -
  • -
  • Maximum text size highlighted for preview Inserting highlights on -search term inside the text before inserting it in the preview window -involves quite a lot of processing, and can be disabled over the -given text size to speed up loading.

    -
  • -
  • Prefer HTML to plain text for preview if set, Recoll will display -HTML as such inside the preview window. If this causes problems with -the Qt HTML display, you can uncheck it to display the plain text -version instead.

    -
  • -
  • Activate links in preview if set, Recoll will turn HTTP links found -inside plain text into proper HTML anchors, and clicking a link -inside a preview window will start the default browser on the link -target.

    -
  • -
  • Plain text to HTML line style: when displaying plain text inside the -preview window, RCL tries to preserve some of the original text line -breaks and indentation. It can either use PRE HTML tags, which will -well preserve the indentation but will force horizontal scrolling for -long lines, or use BR tags to break at the original line breaks, -which will let the editor introduce other line breaks according to -the window width, but will lose some of the original indentation. The -third option has been available in recent releases and is probably -now the best one: use PRE tags with line wrapping.

    -
  • -
  • Choose editor application: this opens a dialog which allows you to -select the application to be used to open each MIME type. The default -is to use the xdg-open utility, but you can use this dialog to -override it, setting exceptions for MIME types that will still be -opened according to RCL preferences. This is useful for passing -parameters like page numbers or search strings to applications that -support them (e.g. evince). This cannot be done with xdg-open -which only supports passing one parameter.

    -
  • -
  • Disable Qt autocompletion in search entry: this will disable the -completion popup. Il will only appear, and display the full history, -either if you enter only white space in the search area, or if you -click the clock button on the right of the area.

    -
  • -
  • Document filter choice style: this will let you choose if the -document categories are displayed as a list or a set of buttons, or a -menu.

    -
  • -
  • Start with simple search mode: this lets you choose the value of the -simple search type on program startup. Either a fixed value (e.g. -Query Language, or the value in use when the program last exited.

    -
  • -
  • Start with advanced search dialog open: If you use this dialog -frequently, checking the entries will get it to open when recoll -starts.

    -
  • -
  • Remember sort activation state if set, Recoll will remember the sort -tool stat between invocations. It normally starts with sorting -disabled.

    -
  • -
-

Result list parameters:.

-
    -
  • Number of results in a result page
  • -
  • Result list font: There is quite a lot of information shown in the -result list, and you may want to customize the font and/or font size. -The rest of the fonts used by RCL are determined by your generic Qt -config (try the qtconfig command).
  • -
  • Edit result list paragraph format string: allows you to change the -presentation of each result list entry. See the result list -customisation section.
  • -
  • Edit result page HTML header insert: allows you to define text -inserted at the end of the result page HTML header. More detail in -the result list customisation -section.
  • -
  • Date format: allows specifying the format used for displaying dates -inside the result list. This should be specified as an strftime() -string (man strftime).
  • -
  • Abstract snippet separator: for synthetic abstracts built from index -data, which are usually made of several snippets from different parts -of the document, this defines the snippet separator, an ellipsis by -default.
  • -
-

Search parameters:.

-
    -
  • Hide duplicate results: decides if result list entries are shown for -identical documents found in different places.
  • -
  • Stemming language: stemming obviously depends on the document’s -language. This listbox will let you chose among the stemming -databases which were built during indexing (this is set in the main -configuration file), or later -added with recollindex -s (See the recollindex manual). Stemming -languages which are dynamically added will be deleted at the next -indexing pass unless they are also added in the configuration file.
  • -
  • Automatically add phrase to simple searches: a phrase will be -automatically built and added to simple searches when looking for -Any terms. This will give a relevance boost to the results where -the search terms appear as a phrase (consecutive and in order).
  • -
  • Autophrase term frequency threshold percentage: very frequent terms -should not be included in automatic phrase searches for performance -reasons. The parameter defines the cutoff percentage (percentage of -the documents where the term appears).
  • -
  • Replace abstracts from documents: this decides if we should -synthesize and display an abstract in place of an explicit abstract -found within the document itself.
  • -
  • Dynamically build abstracts: this decides if RCL tries to build -document abstracts (lists of snippets) when displaying the result -list. Abstracts are constructed by taking context from the document -information, around the search terms.
  • -
  • Synthetic abstract size: adjust to taste...
  • -
  • Synthetic abstract context words: how many words should be displayed -around each term occurrence.
  • -
  • Query language magic file name suffixes: a list of words which -automatically get turned into ext:xxx file name suffix clauses -when starting a query language query (e.g.: doc xls xlsx...). -This will save some typing for people who use file types a lot when -querying.
  • -
-

External indexes:.

-

This panel will let you browse for additional indexes that you may want -to search. External indexes are designated by their database directory -(ie: /home/someothergui/.recoll/xapiandb, -/usr/local/recollglobal/xapiandb).

-

Once entered, the indexes will appear in the External indexes list, and -you can chose which ones you want to use at any moment by checking or -unchecking their entries.

-

Your main database (the one the current configuration indexes to), is -always implicitly active. If this is not desirable, you can set up your -configuration so that it indexes, for example, an empty directory. An -alternative indexer may also need to implement a way of purging the -index from stale data,

-
-
The result list format
-

Newer versions of Recoll (from 1.17) normally use WebKit HTML widgets -for the result list and the snippets -window (this may be -disabled at build time). Total customisation is possible with full -support for CSS and Javascript. Conversely, there are limits to what you -can do with the older Qt QTextBrowser, but still, it is possible to -decide what data each result will contain, and how it will be displayed.

-

The result list presentation can be exhaustively customized by adjusting -two elements:

-
    -
  • The paragraph format
  • -
  • HTML code inside the header section. For versions 1.21 and later, -this is also used for the snippets -window
  • -
-

The paragraph format and the header fragment can be edited from the -Result list tab of the GUI configuration.

-

The header fragment is used both for the result list and the snippets -window. The snippets list is a table and has a snippets class -attribute. Each paragraph in the result list is a table, with class -respar, but this can be changed by editing the paragraph format.

-

There are a few examples on the page about customising the result -list on the RCL web site.

-
-
The paragraph format
-

This is an arbitrary HTML string where the following printf-like % -substitutions will be performed:

-
    -
  • %A.

    -

    Abstract

    -
  • -
  • %D.

    -

    Date

    -
  • -
  • %I.

    -

    Icon image name. This is normally determined from the MIME type. The -associations are defined inside the `mimeconf configuration -file <#RCL.INSTALL.CONFIG.MIMECONF>`__. If a thumbnail for the file -is found at the standard Freedesktop location, this will be displayed -instead.

    -
  • -
  • %K.

    -

    Keywords (if any)

    -
  • -
  • %L.

    -

    Precooked Preview, Edit, and possibly Snippets links

    -
  • -
  • %M.

    -

    MIME type

    -
  • -
  • %N.

    -

    result Number inside the result page

    -
  • -
  • %P.

    -

    Parent folder Url. In the case of an embedded document, this is the -parent folder for the top level container file.

    -
  • -
  • %R.

    -

    Relevance percentage

    -
  • -
  • %S.

    -

    Size information

    -
  • -
  • %T.

    -

    Title or Filename if not set.

    -
  • -
  • %t.

    -

    Title or empty.

    -
  • -
  • %(filename).

    -

    File name.

    -
  • -
  • %U.

    -

    Url

    -
  • -
-

The format of the Preview, Edit, and Snippets links is -<a href="P%N">, <a href="E%N"> and <a href="A%N"> where -docnum (%N) expands to the document number inside the result page).

-

A link target defined as "F%N" will open the document corresponding -to the %P parent folder expansion, usually creating a file manager -window on the folder where the container file resides. E.g.:

-
<a href="F%N">%P</a>
-
-
-

A link target defined as R%N|scriptname will run the corresponding -script on the result file (if the document is embedded, the script will -be started on the top-level parent). See the section about defining -scripts.

-

In addition to the predefined values above, all strings like -%(fieldname) will be replaced by the value of the field named -fieldname for this document. Only stored fields can be accessed in -this way, the value of indexed but not stored fields is not known at -this point in the search process (see field -configuration). There are currently very few -fields stored by default, apart from the values above (only author -and filename), so this feature will need some custom local -configuration to be useful. An example candidate would be the -recipient field which is generated by the message input handlers.

-

The default value for the paragraph format string is:

-
"<table class=\"respar\">\n"
-"<tr>\n"
-"<td><a href='%U'><img src='%I' width='64'></a></td>\n"
-"<td>%L &nbsp;<i>%S</i> &nbsp;&nbsp;<b>%T</b><br>\n"
-"<span style='white-space:nowrap'><i>%M</i>&nbsp;%D</span>&nbsp;&nbsp;&nbsp; <i>%U</i>&nbsp;%i<br>\n"
-"%A %K</td>\n"
-"</tr></table>\n"
-
-
-

You may, for example, try the following for a more web-like experience:

-
<u><b><a href="P%N">%T</a></b></u><br>
-%A<font color=#008000>%U - %S</font> - %L
-
-
-

Note that the P%N link in the above paragraph makes the title a preview -link. Or the clean looking:

-
<img src="%I" align="left">%L <font color="#900000">%R</font>
-&nbsp;&nbsp;<b>%T&</b><br>%S&nbsp;
-<font color="#808080"><i>%U</i></font>
-<table bgcolor="#e0e0e0">
-<tr><td><div>%A</div></td></tr>
-</table>%K
-
-
-

These samples, and some others are on the web site, with pictures to -show how they look.

-

It is also possible to define the value of the snippet separator inside -the abstract section.

-
-
-
-
-
-

Searching with the KDE KIO slave

-
-

What’s this

-

The RCL KIO slave allows performing a RCL search by entering an -appropriate URL in a KDE open dialog, or with an HTML-based interface -displayed in Konqueror.

-

The HTML-based interface is similar to the Qt-based interface, but -slightly less powerful for now. Its advantage is that you can perform -your search while staying fully within the KDE framework: drag and drop -from the result list works normally and you have your normal choice of -applications for opening files.

-

The alternative interface uses a directory view of search results. Due -to limitations in the current KIO slave interface, it is currently not -obviously useful (to me).

-

The interface is described in more detail inside a help file which you -can access by entering recoll:/ inside the konqueror URL line -(this works only if the recoll KIO slave has been previously installed).

-

The instructions for building this module are located in the source -tree. See: kde/kio/recoll/00README.txt. Some Linux distributions do -package the kio-recoll module, so check before diving into the build -process, maybe it’s already out there ready for one-click installation.

-
-
-

Searchable documents

-

As a sample application, the RCL KIO slave could allow preparing a set -of HTML documents (for example a manual) so that they become their own -search interface inside konqueror.

-

This can be done by either explicitly inserting -<a href="recoll://..."> links around some document areas, or -automatically by adding a very small javascript program to the -documents, like the following example, which would initiate a search by -double-clicking any term:

-
<script language="JavaScript">
-        function recollsearch() {
-        var t = document.getSelection();
-        window.location.href = 'recoll://search/query?qtp=a&p=0&q=' +
-        encodeURIComponent(t);
-        }
-        </script>
-        ....
-        <body ondblclick="recollsearch()">
-
-
-
-
-
-

Searching on the command line

-

There are several ways to obtain search results as a text stream, -without a graphical interface:

-
    -
  • By passing option -t to the recoll program, or by calling it -as recollq (through a link).
  • -
  • By using the recollq program.
  • -
  • By writing a custom Python program, using the Recoll Python -API.
  • -
-

The first two methods work in the same way and accept/need the same -arguments (except for the additional -t to recoll). The query to -be executed is specified as command line arguments.

-

recollq is not built by default. You can use the Makefile in the -query directory to build it. This is a very simple program, and if -you can program a little c++, you may find it useful to taylor its -output format to your needs. Not that recollq is only really useful on -systems where the Qt libraries (or even the X11 ones) are not available. -Otherwise, just use recoll -t, which takes the exact same parameters -and options which are described for recollq

-

recollq has a man page (not installed by default, look in the -doc/man directory). The Usage string is as follows:

-
recollq: usage:
--P: Show the date span for all the documents present in the index
-[-o|-a|-f] [-q] <query string>
-Runs a recoll query and displays result lines.
-Default: will interpret the argument(s) as a xesam query string
-query may be like:
-implicit AND, Exclusion, field spec:    t1 -t2 title:t3
-OR has priority: t1 OR t2 t3 OR t4 means (t1 OR t2) AND (t3 OR t4)
-Phrase: "t1 t2" (needs additional quoting on cmd line)
--o Emulate the GUI simple search in ANY TERM mode
--a Emulate the GUI simple search in ALL TERMS mode
--f Emulate the GUI simple search in filename mode
--q is just ignored (compatibility with the recoll GUI command line)
-Common options:
--c <configdir> : specify config directory, overriding $RECOLL_CONFDIR
--d also dump file contents
--n [first-]<cnt> define the result slice. The default value for [first]
-is 0. Without the option, the default max count is 2000.
-Use n=0 for no limit
--b : basic. Just output urls, no mime types or titles
--Q : no result lines, just the processed query and result count
--m : dump the whole document meta[] array for each result
--A : output the document abstracts
--S fld : sort by field <fld>
--s stemlang : set stemming language to use (must exist in index...)
-Use -s "" to turn off stem expansion
--D : sort descending
--i <dbdir> : additional index, several can be given
--e use url encoding (%xx) for urls
--F <field name list> : output exactly these fields for each result.
-The field values are encoded in base64, output in one line and
-separated by one space character. This is the recommended format
-for use by other programs. Use a normal query with option -m to
-see the field names.
-
-
-

Sample execution:

-
recollq 'ilur -nautique mime:text/html'
-      Recoll query: ((((ilur:(wqf=11) OR ilurs) AND_NOT (nautique:(wqf=11)
-      OR nautiques OR nautiqu OR nautiquement)) FILTER Ttext/html))
-      4 results
-      text/html       [file:///Users/uncrypted-dockes/projets/bateaux/ilur/comptes.html]      [comptes.html]  18593   bytes
-      text/html       [file:///Users/uncrypted-dockes/projets/nautique/webnautique/articles/ilur1/index.html] [Constructio...
-      text/html       [file:///Users/uncrypted-dockes/projets/pagepers/index.html]    [psxtcl/writemime/recoll]...
-      text/html       [file:///Users/uncrypted-dockes/projets/bateaux/ilur/factEtCie/recu-chasse-maree....
-
-
-
-
-

Using Synonyms (1.22)

-

Term synonyms:.

-

there are a number of ways to use term synonyms for searching text:

-
    -
  • At index creation time, they can be used to alter the indexed terms, -either increasing or decreasing their number, by expanding the -original terms to all synonyms, or by reducing all synonym terms to a -canonical one.
  • -
  • At query time, they can be used to match texts containing terms which -are synonyms of the ones specified by the user, either by expanding -the query for all synonyms, or by reducing the user entry to -canonical terms (the latter only works if the corresponding -processing has been performed while creating the index).
  • -
-

RCL only uses synonyms at query time. A user query term which part of a -synonym group will be optionally expanded into an OR query for all -terms in the group.

-

Synonym groups are defined inside ordinary text files. Each line in the -file defines a group.

-

Example:

-
hi hello "good morning"
-
-# not sure about "au revoir" though. Is this english ?
-bye goodbye "see you" \
-"au revoir"
-
-
-

As usual, lines beginning with a # are comments, empty lines are -ignored, and lines can be continued by ending them with a backslash.

-

Multi-word synonyms are supported, but be aware that these will generate -phrase queries, which may degrade performance and will disable stemming -expansion for the phrase terms.

-

The synonyms file can be specified in the Search parameters tab of the -GUI configuration Preferences menu entry, or as an option for -command-line searches.

-

Once the file is defined, the use of synonyms can be enabled or disabled -directly from the Preferences menu.

-

The synonyms are searched for matches with user terms after the latter -are stem-expanded, but the contents of the synonyms file itself is not -subjected to stem expansion. This means that a match will not be found -if the form present in the synonyms file is not present anywhere in the -document set.

-

The synonyms function is probably not going to help you find your -letters to Mr. Smith. It is best used for domain-specific searches. For -example, it was initially suggested by a user performing searches among -historical documents: the synonyms file would contains nicknames and -aliases for each of the persons of interest.

-
-
-

Path translations

-

In some cases, the document paths stored inside the index do not match -the actual ones, so that document previews and accesses will fail. This -can occur in a number of circumstances:

-
    -
  • When using multiple indexes it is a relatively common occurrence that -some will actually reside on a remote volume, for exemple mounted via -NFS. In this case, the paths used to access the documents on the -local machine are not necessarily the same than the ones used while -indexing on the remote machine. For example, /home/me may have -been used as a topdirs elements while indexing, but the directory -might be mounted as /net/server/home/me on the local machine.
  • -
  • The case may also occur with removable disks. It is perfectly -possible to configure an index to live with the documents on the -removable disk, but it may happen that the disk is not mounted at the -same place so that the documents paths from the index are invalid.
  • -
  • As a last exemple, one could imagine that a big directory has been -moved, but that it is currently inconvenient to run the indexer.
  • -
-

RCL has a facility for rewriting access paths when extracting the data -from the index. The translations can be defined for the main index and -for any additional query index.

-

The path translation facility will be useful whenever the documents -paths seen by the indexer are not the same as the ones which should be -used at query time.

-

In the above NFS example, RCL could be instructed to rewrite any -file:///home/me URL from the index to -file:///net/server/home/me, allowing accesses from the client.

-

The translations are defined in the -`ptrans <#RCL.INSTALL.CONFIG.PTRANS>`__ configuration file, which -can be edited by hand or from the GUI external indexes configuration -dialog: Preferences > External index dialog, then click the Paths -translations button on the right below the index list.

-
-

Note

-

Due to a current bug, the GUI must be restarted after changing the -ptrans values (even when they were changed from the GUI).

-
-
-
-

The query language

-

The query language processor is activated in the GUI simple search entry -when the search mode selector is set to Query Language. It can also be -used with the KIO slave or the command line search. It broadly has the -same capabilities as the complex search interface in the GUI.

-

The language was based on the now defunct -Xesam user -search language specification.

-

If the results of a query language search puzzle you and you doubt what -has been actually searched for, you can use the GUI Show Query link -at the top of the result list to check the exact query which was finally -executed by Xapian.

-

Here follows a sample request that we are going to explain:

-
author:"john doe" Beatles OR Lennon Live OR Unplugged -potatoes
-
-
-

This would search for all documents with John Doe appearing as a phrase -in the author field (exactly what this is would depend on the document -type, ie: the From: header, for an email message), and containing -either beatles or lennon and either live or unplugged but not potatoes -(in any part of the document).

-

An element is composed of an optional field specification, and a value, -separated by a colon (the field separator is the last colon in the -element). Examples: Eugenie, author:balzac, dc:title:grandet -dc:title:”eugenie grandet”

-

The colon, if present, means “contains”. Xesam defines other relations, -which are mostly unsupported for now (except in special cases, described -further down).

-

All elements in the search entry are normally combined with an implicit -AND. It is possible to specify that elements be OR’ed instead, as in -Beatles OR Lennon. The OR must be entered literally (capitals), -and it has priority over the AND associations: word1 word2 OR word3 -means word1 AND (word2 OR word3) not (word1 AND word2) OR word3.

-

RCL versions 1.21 and later, allow using parentheses to group elements, -which will sometimes make things clearer, and may allow expressing -combinations which would have been difficult otherwise.

-

An element preceded by a - specifies a term that should not -appear.

-

As usual, words inside quotes define a phrase (the order of words is -significant), so that title:”prejudice pride” is not the same as -title:prejudice title:pride, and is unlikely to find a result.

-

Words inside phrases and capitalized words are not stem-expanded. -Wildcards may be used anywhere inside a term. Specifying a wild-card on -the left of a term can produce a very slow search (or even an incorrect -one if the expansion is truncated because of excessive size). Also see -More about wildcards.

-

To save you some typing, recent RCL versions (1.20 and later) interpret -a comma-separated list of terms as an AND list inside the field. Use -slash characters (‘/’) for an OR list. No white space is allowed. So

-
author:john,lennon
-
-
-

will search for documents with john and lennon inside the -author field (in any order), and

-
author:john/ringo
-
-
-

would search for john or ringo.

-

Modifiers can be set on a double-quote value, for example to specify a -proximity search (unordered). See the modifier -section. No space must separate the -final double-quote and the modifiers value, e.g. “two one”po10

-

RCL currently manages the following default fields:

-
    -
  • title, subject or caption are synonyms which specify data -to be searched for in the document title or subject.
  • -
  • author or from for searching the documents originators.
  • -
  • recipient or to for searching the documents recipients.
  • -
  • keyword for searching the document-specified keywords (few -documents actually have any).
  • -
  • filename for the document’s file name. This is not necessarily -set for all documents: internal documents contained inside a compound -one (for example an EPUB section) do not inherit the container file -name any more, this was replaced by an explicit field (see next). -Sub-documents can still have a specific filename, if it is -implied by the document format, for example the attachment file name -for an email attachment.
  • -
  • containerfilename. This is set for all documents, both top-level -and contained sub-documents, and is always the name of the filesystem -directory entry which contains the data. The terms from this field -can only be matched by an explicit field specification (as opposed to -terms from filename which are also indexed as general document -content). This avoids getting matches for all the sub-documents when -searching for the container file name.
  • -
  • ext specifies the file name extension (Ex: ext:html)
  • -
-

RCL 1.20 and later have a way to specify aliases for the field names, -which will save typing, for example by aliasing filename to fn or -containerfilename to cfn. See the section about the ``fields` -file <#RCL.INSTALL.CONFIG.FIELDS>`__

-

The document input handlers used while indexing have the possibility to -create other fields with arbitrary names, and aliases may be defined in -the configuration, so that the exact field search possibilities may be -different for you if someone took care of the customisation.

-

The field syntax also supports a few field-like, but special, criteria:

-
    -
  • dir for filtering the results on file location (Ex: -dir:/home/me/somedir). -dir also works to find results not in -the specified directory (release >= 1.15.8). Tilde expansion will be -performed as usual (except for a bug in versions 1.19 to 1.19.11p1). -Wildcards will be expanded, but please have a -look at an important limitation of -wildcards in path filters.

    -

    Relative paths also make sense, for example, dir:share/doc would -match either /usr/share/doc or /usr/local/share/doc

    -

    Several dir clauses can be specified, both positive and negative. -For example the following makes sense:

    -
    dir:recoll dir:src -dir:utils -dir:common
    -
    -
    -

    This would select results which have both recoll and src in -the path (in any order), and which have not either utils or -common.

    -

    You can also use OR conjunctions with dir: clauses.

    -

    A special aspect of dir clauses is that the values in the index -are not transcoded to UTF-8, and never lower-cased or unaccented, but -stored as binary. This means that you need to enter the values in the -exact lower or upper case, and that searches for names with -diacritics may sometimes be impossible because of character set -conversion issues. Non-ASCII UNIX file paths are an unending source -of trouble and are best avoided.

    -

    You need to use double-quotes around the path value if it contains -space characters.

    -
  • -
  • size for filtering the results on file size. Example: -size<10000. You can use <, > or = as operators. You -can specify a range like the following: size>100 size<1000. The -usual k/K, m/M, g/G, t/T can be used as (decimal) multipliers. -Ex: size>1k to search for files bigger than 1000 bytes.

    -
  • -
  • date for searching or filtering on dates. The syntax for the -argument is based on the ISO8601 standard for dates and time -intervals. Only dates are supported, no times. The general syntax is -2 elements separated by a / character. Each element can be a date -or a period of time. Periods are specified as -PnYnMnD. The n numbers are the respective -numbers of years, months or days, any of which may be missing. Dates -are specified as YYYY-MM-DD. The days and months parts may be -missing. If the / is present but an element is missing, the -missing element is interpreted as the lowest or highest date in the -index. Examples:

    -
      -
    • 2001-03-01/2002-05-01 the basic syntax for an interval of -dates.
    • -
    • 2001-03-01/P1Y2M the same specified with a period.
    • -
    • 2001/ from the beginning of 2001 to the latest date in the -index.
    • -
    • 2001 the whole year of 2001
    • -
    • P2D/ means 2 days ago up to now if there are no documents with -dates in the future.
    • -
    • /2003 all documents from 2003 or older.
    • -
    -

    Periods can also be specified with small letters (ie: p2y).

    -
  • -
  • mime or format for specifying the MIME type. These clauses -are processed besides the normal Boolean logic of the search. -Multiple values will be OR’ed (instead of the normal AND). You can -specify types to be excluded, with the usual -, and use -wildcards. Example: mime:text/* -mime:text/plain Specifying an -explicit boolean operator before a mime specification is not -supported and will produce strange results.

    -
  • -
  • type or rclcat for specifying the category (as in -text/media/presentation/etc.). The classification of MIME types in -categories is defined in the RCL configuration (mimeconf), and -can be modified or extended. The default category names are those -which permit filtering results in the main GUI screen. Categories are -OR’ed like MIME types above, and can be negated with -.

    -
    -

    Note

    -

    mime, rclcat, size and date criteria always affect -the whole query (they are applied as a final filter), even if set -with other terms inside a parenthese.

    -

    Note

    -

    mime (or the equivalent rclcat) is the only field with an -OR default. You do need to use OR with ext terms for -example.

    -
    -
  • -
-
-

Range clauses

-

RCL 1.24 and later support range clauses on fields which have been -configured to support it. No default field uses them currently, so this -paragraph is only interesting if you modified the fields configuration -and possibly use a custom input handler.

-

A range clause looks like one of the following:

-
myfield:small..big
-myfield:small..
-myfield:..big
-
-
-

The nature of the clause is indicated by the two dots .., and the -effect is to filter the results for which the myfield value is in the -possibly open-ended interval.

-

See the section about the `fields configuration -file <#RCL.INSTALL.CONFIG.FIELDS>`__ for the details of configuring a -field for range searches (list them in the [values] section).

-
-
-

Modifiers

-

Some characters are recognized as search modifiers when found -immediately after the closing double quote of a phrase, as in -"some term"modifierchars. The actual “phrase” can be a single term -of course. Supported modifiers:

-
    -
  • l can be used to turn off stemming (mostly makes sense with p -because stemming is off by default for phrases).
  • -
  • s can be used to turn off synonym expansion, if a synonyms file -is in place (only for RCL 1.22 and later).
  • -
  • o can be used to specify a “slack” for phrase and proximity -searches: the number of additional terms that may be found between -the specified ones. If o is followed by an integer number, this -is the slack, else the default is 10.
  • -
  • p can be used to turn the default phrase search into a proximity -one (unordered). Example: "order any in"p
  • -
  • C will turn on case sensitivity (if the index supports it).
  • -
  • D will turn on diacritics sensitivity (if the index supports it).
  • -
  • A weight can be specified for a query element by specifying a decimal -value at the start of the modifiers. Example: "Important"2.5.
  • -
-
-
-
-

Search case and diacritics sensitivity

-

For RCL versions 1.18 and later, and when working with a raw index -(not the default), searches can be sensitive to character case and -diacritics. How this happens is controlled by configuration variables -and what search data is entered.

-

The general default is that searches entered without upper-case or -accented characters are insensitive to case and diacritics. An entry of -resume will match any of Resume, RESUME, résumé, -Résumé etc.

-

Two configuration variables can automate switching on sensitivity (they -were documented but actually did nothing until RCL 1.22):

-
-
autodiacsens
-
If this is set, search sensitivity to diacritics will be turned on -as soon as an accented character exists in a search term. When the -variable is set to true, resume will start a -diacritics-unsensitive search, but résumé will be matched -exactly. The default value is false.
-
autocasesens
-
If this is set, search sensitivity to character case will be turned -on as soon as an upper-case character exists in a search term -except for the first one. When the variable is set to true, us -or Us will start a diacritics-unsensitive search, but US -will be matched exactly. The default value is true (contrary to -autodiacsens).
-
-

As in the past, capitalizing the first letter of a word will turn off -its stem expansion and have no effect on case-sensitivity.

-

You can also explicitely activate case and diacritics sensitivity by -using modifiers with the query language. C will make the term -case-sensitive, and D will make it diacritics-sensitive. Examples:

-
"us"C
-
-
-

will search for the term us exactly (Us will not be a match).

-
"resume"D
-
-
-

will search for the term resume exactly (résumé will not be a -match).

-

When either case or diacritics sensitivity is activated, stem expansion -is turned off. Having both does not make much sense.

-
-
-

Anchored searches and wildcards

-

Some special characters are interpreted by RCL in search strings to -expand or specialize the search. Wildcards expand a root term in -controlled ways. Anchor characters can restrict a search to succeed only -if the match is found at or near the beginning of the document or one of -its fields.

-
-

More about wildcards

-

All words entered in RCL search fields will be processed for wildcard -expansion before the request is finally executed.

-

The wildcard characters are:

-
    -
  • * which matches 0 or more characters.
  • -
  • ? which matches a single character.
  • -
  • [] which allow defining sets of characters to be matched (ex: -[abc] matches a single character which may be ‘a’ or -‘b’ or ‘c’, [0-9] matches any number.
  • -
-

You should be aware of a few things when using wildcards.

-
    -
  • Using a wildcard character at the beginning of a word can make for a -slow search because RCL will have to scan the whole index term list -to find the matches. However, this is much less a problem for field -searches, and queries like author:*@domain.com can sometimes be very -useful.
  • -
  • For RCL version 18 only, when working with a raw index (preserving -character case and diacritics), the literal part of a wildcard -expression will be matched exactly for case and diacritics. This is -not true any more for versions 19 and later.
  • -
  • Using a * at the end of a word can produce more matches than you -would think, and strange search results. You can use the term -explorer tool to check what -completions exist for a given term. You can also see exactly what -search was performed by clicking on the link at the top of the result -list. In general, for natural language terms, stem expansion will -produce better results than an ending * (stem expansion is turned -off when any wildcard character appears in the term).
  • -
-
-
Wildcards and path filtering
-

Due to the way that RCL processes wildcards inside dir path -filtering clauses, they will have a multiplicative effect on the query -size. A clause containg wildcards in several paths elements, like, for -example, dir:/home/me/*/*/docdir, will almost certainly fail if -your indexed tree is of any realistic size.

-

Depending on the case, you may be able to work around the issue by -specifying the paths elements more narrowly, with a constant prefix, or -by using 2 separate dir: clauses instead of multiple wildcards, as -in dir:/home/me dir:docdir. The latter query is not equivalent -to the initial one because it does not specify a number of directory -levels, but that’s the best we can do (and it may be actually more -useful in some cases).

-
-
-
-

Anchored searches

-

Two characters are used to specify that a search hit should occur at the -beginning or at the end of the text. ^ at the beginning of a term or -phrase constrains the search to happen at the start, $ at the end -force it to happen at the end.

-

As this function is implemented as a phrase search it is possible to -specify a maximum distance at which the hit should occur, either through -the controls of the advanced search panel, or using the query language, -for example, as in:

-
"^someterm"o10
-
-
-

which would force someterm to be found within 10 terms of the start -of the text. This can be combined with a field search as in -somefield:"^someterm"o10 or somefield:someterm$.

-

This feature can also be used with an actual phrase search, but in this -case, the distance applies to the whole phrase and anchor, so that, for -example, bla bla my unexpected term at the beginning of the text -would be a match for "^my term"o5.

-

Anchored searches can be very useful for searches inside somewhat -structured documents like scientific articles, in case explicit metadata -has not been supplied (a most frequent case), for example for looking -for matches inside the abstract or the list of authors (which occur at -the top of the document).

-
-
-
-

Desktop integration

-

Being independant of the desktop type has its drawbacks: RCL desktop -integration is minimal. However there are a few tools available:

- -

Here follow a few other things that may help.

-
-

Hotkeying recoll

-

It is surprisingly convenient to be able to show or hide the RCL GUI -with a single keystroke. Recoll comes with a small Python script, based -on the libwnck window manager interface library, which will allow you to -do just this. The detailed instructions are on this wiki -page.

-
-
-

The KDE Kicker Recoll applet

-

This is probably obsolete now. Anyway:

-

The RCL source tree contains the source code to the recoll_applet, a -small application derived from the find_applet. This can be used to add -a small RCL launcher to the KDE panel.

-

The applet is not automatically built with the main RCL programs, nor is -it included with the main source distribution (because the KDE build -boilerplate makes it relatively big). You can download its source from -the recoll.org download page. Use the omnipotent -configure;make;make install incantation to build and install.

-

You can then add the applet to the panel by right-clicking the panel and -choosing the Add applet entry.

-

The recoll_applet has a small text window where you can type a RCL -query (in query language form), and an icon which can be used to -restrict the search to certain types of files. It is quite primitive, -and launches a new recoll GUI instance every time (even if it is already -running). You may find it useful anyway.

-
-
-
-
-

Removable volumes

-

RCL used to have no support for indexing removable volumes (portable -disks, USB keys, etc.). Recent versions have improved the situation and -support indexing removable volumes in two different ways:

-
    -
  • By storing a volume index on the volume itself (RCL 1.24).
  • -
  • By indexing the volume in the main, fixed, index, and ensuring that -the volume data is not purged if the indexing runs while the volume -is mounted. (RCL 1.25.2).
  • -
-
-

Indexing removable volumes in the main index

-

As of version 1.25.2, RCL has a simple way to ensure that the index data -for an absent volume will not be purged: the volume mount point must be -a member of the topdirs list, and the mount directory must be empty -(when the volume is not mounted). If recollindex finds that one of -the topdirs is empty when starting up, any existing data for the -tree will be preserved by the indexing pass (no purge for this area).

-
-
-

Self contained volumes

-

As of RCL 1.24, it has become easy to build self-contained datasets -including a RCL configuration directory and index together with the -indexed documents, and to move such a dataset around (for example -copying it to an USB drive), without having to adjust the configuration -for querying the index.

-
-

Note

-

This is a query-time feature only. The index must only be updated in -its original location. If an update is necessary in a different -location, the index must be reset.

-
-

To make a long story short, here follows a script to create a RCL -configuration and index under a given directory (given as single -parameter). The resulting data set (files + recoll directory) can later -to be moved to a CDROM or thumb drive. Longer explanations come after -the script.

-
#!/bin/sh
-
-fatal()
-{
-    echo $*;exit 1
-}
-usage()
-{
-    fatal "Usage: init-recoll-volume.sh <top-directory>"
-}
-
-test $# = 1 || usage
-topdir=$1
-test -d "$topdir" || fatal $topdir should be a directory
-
-confdir="$topdir/recoll-config"
-test ! -d "$confdir" || fatal $confdir should not exist
-
-mkdir "$confdir"
-cd "$topdir"
-topdir=`pwd`
-cd "$confdir"
-confdir=`pwd`
-
-(echo topdirs = '"'$topdir'"'; \
- echo orgidxconfdir = $topdir/recoll-config) > "$confdir/recoll.conf"
-
-recollindex -c "$confdir"
-
-
-

The examples below will assume that you have a dataset under -/home/me/mydata/, with the index configuration and data stored -inside /home/me/mydata/recoll-confdir.

-

In order to be able to run queries after the dataset has been moved, you -must ensure the following:

-
    -
  • The main configuration file must define the -orgidxconfdir -variable to be the original location of the configuration directory -(orgidxconfdir=/home/me/mydata/recoll-confdir must be set inside -/home/me/mydata/recoll-confdir/recoll.conf in the example above).
  • -
  • The configuration directory must exist with the documents, somewhere -under the directory which will be moved. E.g. if you are moving -/home/me/mydata around, the configuration directory must exist -somewhere below this point, for example -/home/me/mydata/recoll-confdir, or -/home/me/mydata/sub/recoll-confdir.
  • -
  • You should keep the default locations for the index elements (they -are relative to the configuration directory by default). Only the -paths referring to the documents themselves (e.g. topdirs values) -should be absolute (in general, they are only used when indexing -anyway).
  • -
-

Only the first point needs an explicit user action, the RCL defaults are -compatible with the second one, and the third is natural.

-

If, after the move, the configuration directory needs to be copied out -of the dataset (for example because the thumb drive is too slow), you -can set the -curidxconfdir, -variable inside the copied configuration to define the location of the -moved one. For example if /home/me/mydata is now mounted onto -/media/me/somelabel, but the configuration directory and index has -been copied to /tmp/tempconfig, you would set curidxconfdir to -/media/me/somelabel/recoll-confdir inside -/tmp/tempconfig/recoll.conf. orgidxconfdir would still be -/home/me/mydata/recoll-confdir in the original and the copy.

-

If you are regularly copying the configuration out of the dataset, it -will be useful to write a script to automate the procedure. This can’t -really be done inside RCL because there are probably many possible -variants. One example would be to copy the configuration to make it -writable, but keep the index data on the medium because it is too big - -in this case, the script would also need to set dbdir in the copied -configuration.

-

The same set of modifications (RCL 1.24) has also made it possible to -run queries from a readonly configuration directory (with slightly -reduced function of course, such as not recording the query history).

-
-
-
-

Programming interface

-

RCL has an Application Programming Interface, usable both for indexing -and searching, currently accessible from the Python language.

-

Another less radical way to extend the application is to write input -handlers for new types of documents.

-

The processing of metadata attributes for documents (fields) is -highly configurable.

-
-

Writing a document input handler

-
-

Note

-

The small programs or pieces of code which handle the processing of -the different document types for RCL used to be called filters, -which is still reflected in the name of the directory which holds -them and many configuration variables. They were named this way -because one of their primary functions is to filter out the -formatting directives and keep the text content. However these -modules may have other behaviours, and the term input handler is -now progressively substituted in the documentation. filter is -still used in many places though.

-
-

RCL input handlers cooperate to translate from the multitude of input -document formats, simple ones as opendocument, acrobat, or compound ones -such as Zip or Email, into the final RCL indexing input format, which is -plain text (in many cases the processing pipeline has an intermediary -HTML step, which may be used for better previewing presentation). Most -input handlers are executable programs or scripts. A few handlers are -coded in C++ and live inside recollindex. This latter kind will not -be described here.

-

There are currently (since version 1.13) two kinds of external -executable input handlers:

-
    -
  • Simple exec handlers run once and exit. They can be bare programs -like antiword, or scripts using other programs. They are very -simple to write, because they just need to print the converted -document to the standard output. Their output can be plain text or -HTML. HTML is usually preferred because it can store metadata fields -and it allows preserving some of the formatting for the GUI preview. -However, these handlers have limitations:
      -
    • They can only process one document per file.
    • -
    • The output MIME type must be known and fixed.
    • -
    • The character encoding, if relevant, must be known and fixed (or -possibly just depending on location).
    • -
    -
  • -
  • Multiple execm handlers can process multiple files (sparing the -process startup time which can be very significant), or multiple -documents per file (e.g.: for archives or multi-chapter -publications). They communicate with the indexer through a simple -protocol, but are nevertheless a bit more complicated than the older -kind. Most of the new handlers are written in Python (exception: -rclimg which is written in Perl because exiftool has no real -Python equivalent). The Python handlers use common modules to factor -out the boilerplate, which can make them very simple in favorable -cases. The subdocuments output by these handlers can be directly -indexable (text or HTML), or they can be other simple or compound -documents that will need to be processed by another handler.
  • -
-

In both cases, handlers deal with regular file system files, and can -process either a single document, or a linear list of documents in each -file. RCL is responsible for performing up to date checks, deal with -more complex embedding and other upper level issues.

-

A simple handler returning a document in text/plain format, can -transfer no metadata to the indexer. Generic metadata, like document -size or modification date, will be gathered and stored by the indexer.

-

Handlers that produce text/html format can return an arbitrary -amount of metadata inside HTML meta tags. These will be processed -according to the directives found in the `fields configuration -file <#RCL.PROGRAM.FIELDS>`__.

-

The handlers that can handle multiple documents per file return a single -piece of data to identify each document inside the file. This piece of -data, called an ipath will be sent back by RCL to extract the -document at query time, for previewing, or for creating a temporary file -to be opened by a viewer. These handlers can also return metadata either -as HTML meta tags, or as named data through the communication -protocol.

-

The following section describes the simple handlers, and the next one -gives a few explanations about the execm ones. You could conceivably -write a simple handler with only the elements in the manual. This will -not be the case for the other ones, for which you will have to look at -the code.

-
-

Simple input handlers

-

RCL simple handlers are usually shell-scripts, but this is in no way -necessary. Extracting the text from the native format is the difficult -part. Outputting the format expected by RCL is trivial. Happily enough, -most document formats have translators or text extractors which can be -called from the handler. In some cases the output of the translating -program is completely appropriate, and no intermediate shell-script is -needed.

-

Input handlers are called with a single argument which is the source -file name. They should output the result to stdout.

-

When writing a handler, you should decide if it will output plain text -or HTML. Plain text is simpler, but you will not be able to add metadata -or vary the output character encoding (this will be defined in a -configuration file). Additionally, some formatting may be easier to -preserve when previewing HTML. Actually the deciding factor is metadata: -RCL has a way to extract metadata from the HTML header and use it for -field searches..

-

The RECOLL_FILTER_FORPREVIEW environment variable (values yes, -no) tells the handler if the operation is for indexing or -previewing. Some handlers use this to output a slightly different -format, for example stripping uninteresting repeated keywords (ie: -Subject: for email) when indexing. This is not essential.

-

You should look at one of the simple handlers, for example rclps for -a starting point.

-

Don’t forget to make your handler executable before testing !

-
-
-

“Multiple” handlers

-

If you can program and want to write an execm handler, it should not -be too difficult to make sense of one of the existing handlers.

-

The existing handlers differ in the amount of helper code which they are -using:

-
    -
  • rclimg is written in Perl and handles the execm protocol all by -itself (showing how trivial it is).
  • -
  • All the Python handlers share at least the rclexecm.py module, -which handles the communication. Have a look at, for example, -rclzip for a handler which uses rclexecm.py directly.
  • -
  • Most Python handlers which process single-document files by executing -another command are further abstracted by using the rclexec1.py -module. See for example rclrtf.py for a simple one, or -rcldoc.py for a slightly more complicated one (possibly executing -several commands).
  • -
  • Handlers which extract text from an XML document by using an XSLT -style sheet are now executed inside recollindex, with only the -style sheet stored in the filters/ directory. These can use a -single style sheet (e.g. abiword.xsl), or two sheets for the data -and metadata (e.g. opendoc-body.xsl and opendoc-meta.xsl). -The mimeconf configuration file defines how the sheets are used, -have a look. Before the C++ import, the xsl-based handlers used a -common module rclgenxslt.py, it is still around but unused. The -handler for OpenXML presentations is still the Python version because -the format did not fit with what the C++ code does. It would be a -good base for another similar issue.
  • -
-

There is a sample trivial handler based on rclexecm.py, with many -comments, not actually used by RCL. It would index a text file as one -document per line. Look for rcltxtlines.py in the src/filters -directory in the online RCL Git -repository (the sample not -in the distributed release at the moment).

-

You can also have a look at the slightly more complex rclzip which -uses Zip file paths as identifiers (ipath).

-

execm handlers sometimes need to make a choice for the nature of the -ipath elements that they use in communication with the indexer. Here -are a few guidelines:

-
    -
  • Use ASCII or UTF-8 (if the identifier is an integer print it, for -example, like printf %d would do).
  • -
  • If at all possible, the data should make some kind of sense when -printed to a log file to help with debugging.
  • -
  • RCL uses a colon (:) as a separator to store a complex path -internally (for deeper embedding). Colons inside the ipath -elements output by a handler will be escaped, but would be a bad -choice as a handler-specific separator (mostly, again, for debugging -issues).
  • -
-

In any case, the main goal is that it should be easy for the handler to -extract the target document, given the file name and the ipath -element.

-

execm handlers will also produce a document with a null ipath -element. Depending on the type of document, this may have some -associated data (e.g. the body of an email message), or none (typical -for an archive file). If it is empty, this document will be useful -anyway for some operations, as the parent of the actual data documents.

-
-
-

Telling RCL about the handler

-

There are two elements that link a file to the handler which should -process it: the association of file to MIME type and the association of -a MIME type with a handler.

-

The association of files to MIME types is mostly based on name suffixes. -The types are defined inside the `mimemap -file <#RCL.INSTALL.CONFIG.MIMEMAP>`__. Example:

-
.doc = application/msword
-
-
-

If no suffix association is found for the file name, RCL will try to -execute a system command (typically file -i or xdg-mime) to -determine a MIME type.

-

The second element is the association of MIME types to handlers in the -`mimeconf file <#RCL.INSTALL.CONFIG.MIMECONF>`__. A sample will -probably be better than a long explanation:

-
[index]
-application/msword = exec antiword -t -i 1 -m UTF-8;\
-mimetype = text/plain ; charset=utf-8
-
-application/ogg = exec rclogg
-
-text/rtf = exec unrtf --nopict --html; charset=iso-8859-1; mimetype=text/html
-
-application/x-chm = execm rclchm
-
-
-

The fragment specifies that:

-
    -
  • application/msword files are processed by executing the -antiword program, which outputs text/plain encoded in -utf-8.
  • -
  • application/ogg files are processed by the rclogg script, -with default output type (text/html, with encoding specified in -the header, or utf-8 by default).
  • -
  • text/rtf is processed by unrtf, which outputs text/html. -The iso-8859-1 encoding is specified because it is not the -utf-8 default, and not output by unrtf in the HTML header -section.
  • -
  • application/x-chm is processed by a persistant handler. This is -determined by the execm keyword.
  • -
-
-
-

Input handler output

-

Both the simple and persistent input handlers can return any MIME type -to Recoll, which will further process the data according to the MIME -configuration.

-

Most input filters filters produce either text/plain or -text/html data. There are exceptions, for example, filters which -process archive file (zip, tar, etc.) will usually return the -documents as they are found, without processing them further.

-

There is nothing to say about text/plain output, except that its -character encoding should be consistent with what is specified in the -mimeconf file.

-

For filters producing HTML, the output could be very minimal like the -following example:

-
<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
-</head>
-<body>
-Some text content
-</body>
-</html>
-
-
-

You should take care to escape some characters inside the text by -transforming them into appropriate entities. At the very minimum, -“&” should be transformed into “&amp;”, “<” should be -transformed into “&lt;”. This is not always properly done by -external helper programs which output HTML, and of course never by those -which output plain text.

-

When encapsulating plain text in an HTML body, the display of a preview -may be improved by enclosing the text inside <pre> tags.

-

The character set needs to be specified in the header. It does not need -to be UTF-8 (RCL will take care of translating it), but it must be -accurate for good results.

-

RCL will process meta tags inside the header as possible document -fields candidates. Documents fields can be processed by the indexer in -different ways, for searching or displaying inside query results. This -is described in a following section.

-

By default, the indexer will process the standard header fields if they -are present: title, meta/description, and meta/keywords are -both indexed and stored for query-time display.

-

A predefined non-standard meta tag will also be processed by RCL -without further configuration: if a date tag is present and has the -right format, it will be used as the document date (for display and -sorting), in preference to the file modification date. The date format -should be as follows:

-
<meta name="date" content="YYYY-mm-dd HH:MM:SS">
-or
-<meta name="date" content="YYYY-mm-ddTHH:MM:SS">
-
-
-

Example:

-
<meta name="date" content="2013-02-24 17:50:00">
-
-
-

Input handlers also have the possibility to “invent” field names. This -should also be output as meta tags:

-
<meta name="somefield" content="Some textual data" />
-
-
-

You can embed HTML markup inside the content of custom fields, for -improving the display inside result lists. In this case, add a (wildly -non-standard) markup attribute to tell RCL that the value is HTML -and should not be escaped for display.

-
<meta name="somefield" markup="html" content="Some <i>textual</i> data" />
-
-
-

As written above, the processing of fields is described in a further -section.

-

Persistent filters can use another, probably simpler, method to produce -metadata, by calling the setfield() helper method. This avoids the -necessity to produce HTML, and any issue with HTML quoting. See, for -example, rclaudio in RCL 1.23 and later for an example of handler -which outputs text/plain and uses setfield() to produce -metadata.

-
-
-

Page numbers

-

The indexer will interpret ^L characters in the handler output as -indicating page breaks, and will record them. At query time, this allows -starting a viewer on the right page for a hit or a snippet. Currently, -only the PDF, Postscript and DVI handlers generate page breaks.

-
-
-
-

Field data processing

-

Fields are named pieces of information in or about documents, like -title, author, abstract.

-

The field values for documents can appear in several ways during -indexing: either output by input handlers as meta fields in the HTML -header section, or extracted from file extended attributes, or added as -attributes of the Doc object when using the API, or again -synthetized internally by RCL.

-

The RCL query language allows searching for text in a specific field.

-

RCL defines a number of default fields. Additional ones can be output by -handlers, and described in the fields configuration file.

-

Fields can be:

-
    -
  • indexed, meaning that their terms are separately stored in -inverted lists (with a specific prefix), and that a field-specific -search is possible.
  • -
  • stored, meaning that their value is recorded in the index data -record for the document, and can be returned and displayed with -search results.
  • -
-

A field can be either or both indexed and stored. This and other aspects -of fields handling is defined inside the fields configuration file.

-

Some fields may also designated as supporting range queries, meaning -that the results may be selected for an interval of its values. See the -configuration section for more details.

-

The sequence of events for field processing is as follows:

-
    -
  • During indexing, recollindex scans all meta fields in HTML -documents (most document types are transformed into HTML at some -point). It compares the name for each element to the configuration -defining what should be done with fields (the fields file)
  • -
  • If the name for the meta element matches one for a field that -should be indexed, the contents are processed and the terms are -entered into the index with the prefix defined in the fields -file.
  • -
  • If the name for the meta element matches one for a field that -should be stored, the content of the element is stored with the -document data record, from which it can be extracted and displayed at -query time.
  • -
  • At query time, if a field search is performed, the index prefix is -computed and the match is only performed against appropriately -prefixed terms in the index.
  • -
  • At query time, the field can be displayed inside the result list by -using the appropriate directive in the definition of the result list -paragraph format. All fields are -displayed on the fields screen of the preview window (which you can -reach through the right-click menu). This is independant of the fact -that the search which produced the results used the field or not.
  • -
-

You can find more information in the section about the ``fields` -file <#RCL.INSTALL.CONFIG.FIELDS>`__, or in comments inside the file.

-

You can also have a look at the example in the FAQs -area, detailing how one could add a page -count field to pdf documents for displaying inside result lists.

-
-
-

Python API

-
-

Introduction

-

The RCL Python programming interface can be used both for searching and -for creating/updating an index. Bindings exist for Python2 and Python3.

-

The search interface is used in a number of active projects: the RCL -Gnome Shell Search Provider, the RCL Web UI, and the upmpdcli UPnP Media -Server, in addition to many small scripts.

-

The index update section of the API may be used to create and update RCL -indexes on specific configurations (separate from the ones created by -recollindex). The resulting databases can be queried alone, or in -conjunction with regular ones, through the GUI or any of the query -interfaces.

-

The search API is modeled along the Python database API specification. -There were two major changes along RCL versions:

-
    -
  • The basis for the RCL API changed from Python database API version -1.0 (RCL versions up to 1.18.1), to version 2.0 (RCL 1.18.2 and -later).
  • -
  • The recoll module became a package (with an internal recoll -module) as of RCL version 1.19, in order to add more functions. For -existing code, this only changes the way the interface must be -imported.
  • -
-

We will describe the new API and package structure here. A paragraph at -the end of this section will explain a few differences and ways to write -code compatible with both versions.

-

The recoll package now contains two modules:

-
    -
  • The recoll module contains functions and classes used to query -(or update) the index.
  • -
  • The rclextract module contains functions and classes used at -query time to access document data.
  • -
-

There is a good chance that your system repository has packages for the -Recoll Python API, sometimes in a package separate from the main one -(maybe named something like python-recoll). Else refer to the Building -from source chapter.

-

As an introduction, the following small sample will run a query and list -the title and url for each of the results. It would work with RCL 1.19 -and later. The python/samples source directory contains several -examples of Python programming with RCL, exercising the extension more -completely, and especially its data extraction features.

-
#!/usr/bin/env python
-
-from recoll import recoll
-
-db = recoll.connect()
-query = db.query()
-nres = query.execute("some query")
-results = query.fetchmany(20)
-for doc in results:
-    print("%s %s" % (doc.url, doc.title))
-
-
-

You can also take a look at the source for the Recoll -WebUI, -the upmpdcli local media -server, -or the Gnome Shell Search -Provider.

-
-
-

Interface elements

-

A few elements in the interface are specific and and need an -explanation.

-
-
ipath
-
This data value (set as a field in the Doc object) is stored, along -with the URL, but not indexed by RCL. Its contents are not -interpreted by the index layer, and its use is up to the -application. For example, the RCL file system indexer uses the -ipath to store the part of the document access path internal to -(possibly imbricated) container documents. ipath in this case is -a vector of access elements (e.g, the first part could be a path -inside a zip file to an archive member which happens to be an mbox -file, the second element would be the message sequential number -inside the mbox etc.). url and ipath are returned in every -search result and define the access to the original document. -ipath is empty for top-level document/files (e.g. a PDF document -which is a filesystem file). The RCL GUI knows about the structure -of the ipath values used by the filesystem indexer, and uses it -for such functions as opening the parent of a given document.
-
udi
-
An udi (unique document identifier) identifies a document. -Because of limitations inside the index engine, it is restricted in -length (to 200 bytes), which is why a regular URI cannot be used. -The structure and contents of the udi is defined by the -application and opaque to the index engine. For example, the -internal file system indexer uses the complete document path (file -path + internal path), truncated to length, the suppressed part -being replaced by a hash value. The udi is not explicit in the -query interface (it is used “under the hood” by the rclextract -module), but it is an explicit element of the update interface.
-
parent_udi
-
If this attribute is set on a document when entering it in the -index, it designates its physical container document. In a -multilevel hierarchy, this may not be the immediate parent. -parent_udi is optional, but its use by an indexer may simplify -index maintenance, as RCL will automatically delete all children -defined by parent_udi == udi when the document designated by -udi is destroyed. e.g. if a Zip archive contains entries -which are themselves containers, like mbox files, all the -subdocuments inside the Zip file (mbox, messages, message -attachments, etc.) would have the same parent_udi, matching the -udi for the Zip file, and all would be destroyed when the -Zip file (identified by its udi) is removed from the index. -The standard filesystem indexer uses parent_udi.
-
Stored and indexed fields
-
The `fields file <#RCL.INSTALL.CONFIG.FIELDS>`__ inside the RCL -configuration defines which document fields are either indexed -(searchable), stored (retrievable with search results), or both. -Apart from a few standard/internal fields, only the stored -fields are retrievable through the Python search interface.
-
-
-
-

Python search interface

-
-
The recoll module
-

The connect() function connects to one or several RCL index(es) and -returns a Db object.

-

This call initializes the recoll module, and it should always be -performed before any other call or object creation.

-
    -
  • confdir may specify a configuration directory. The usual defaults -apply.
  • -
  • extra_dbs is a list of additional indexes (Xapian directories).
  • -
  • writable decides if we can index new data through this -connection.
  • -
-

A Db object is created by a connect() call and holds a connection to -a Recoll index.

-
-
Db.close()
-
Closes the connection. You can’t do anything with the Db object -after this.
-
Db.query(), Db.cursor()
-
These aliases return a blank Query object for this index.
-
Db.setAbstractParams(maxchars, contextwords)
-
Set the parameters used to build snippets (sets of keywords in -context text fragments). maxchars defines the maximum total size -of the abstract. contextwords defines how many terms are shown -around the keyword.
-
-

Db.termMatch(match_type, expr, field=’‘, maxlen=-1, casesens=False, -diacsens=False, lang=’english’)

-
-
Expand an expression against the index term list. Performs the basic -function from the GUI term explorer tool. match_type can be -either of wildcard, regexp or stem. Returns a list of -terms expanded from the input expression.
-

A Query object (equivalent to a cursor in the Python DB API) is -created by a Db.query() call. It is used to execute index searches.

-
-
Query.sortby(fieldname, ascending=True)
-
Sort results by fieldname, in ascending or descending order. Must be -called before executing the search.
-
-

Query.execute(query_string, stemming=1, stemlang=”english”, -fetchtext=False)

-
-
Starts a search for query_string, a RCL search language string. If -the index stores the document texts and fetchtext is True, store -the document extracted text in doc.text.
-
-
Query.executesd(SearchData, fetchtext=False)
-
Starts a search for the query defined by the SearchData object. If -the index stores the document texts and fetchtext is True, store -the document extracted text in doc.text.
-
Query.fetchmany(size=query.arraysize)
-
Fetches the next Doc objects in the current search results, and -returns them as an array of the required size, which is by default -the value of the arraysize data member.
-
Query.fetchone()
-
Fetches the next Doc object from the current search results. -Generates a StopIteration exception if there are no results left.
-
Query.close()
-
Closes the query. The object is unusable after the call.
-
Query.scroll(value, mode=’relative’)
-
Adjusts the position in the current result set. mode can be -relative or absolute.
-
Query.getgroups()
-
Retrieves the expanded query terms as a list of pairs. Meaningful -only after executexx In each pair, the first entry is a list of user -terms (of size one for simple terms, or more for group and phrase -clauses), the second a list of query terms as derived from the user -terms and used in the Xapian Query.
-
Query.getxquery()
-
Return the Xapian query description as a Unicode string. Meaningful -only after executexx.
-
Query.highlight(text, ishtml = 0, methods = object)
-
Will insert <span “class=rclmatch”>, </span> tags around the match -areas in the input text and return the modified text. ishtml can -be set to indicate that the input text is HTML and that HTML special -characters should not be escaped. methods if set should be an -object with methods startMatch(i) and endMatch() which will be -called for each match and should return a begin and end tag
-
Query.makedocabstract(doc, methods = object))
-
Create a snippets abstract for doc (a Doc object) by -selecting text around the match terms. If methods is set, will also -perform highlighting. See the highlight method.
-
Query.__iter__() and Query.next()
-
So that things like for doc in query: will work.
-
Query.arraysize
-
Default number of records processed by fetchmany (r/w).
-
Query.rowcount
-
Number of records returned by the last execute.
-
Query.rownumber
-
Next index to be fetched from results. Normally increments after -each fetchone() call, but can be set/reset before the call to effect -seeking (equivalent to using scroll()). Starts at 0.
-
-

A Doc object contains index data for a given document. The data is -extracted from the index when searching, or set by the indexer program -when updating. The Doc object has many attributes to be read or set by -its user. It mostly matches the Rcl::Doc C++ object. Some of the -attributes are predefined, but, especially when indexing, others can be -set, the name of which will be processed as field names by the indexing -configuration. Inputs can be specified as Unicode or strings. Outputs -are Unicode objects. All dates are specified as Unix timestamps, printed -as strings. Please refer to the rcldb/rcldoc.cpp C++ file for a full -description of the predefined attributes. Here follows a short list.

-
    -
  • url the document URL but see also getbinurl()
  • -
  • ipath the document ipath for embedded documents.
  • -
  • fbytes, dbytes the document file and text sizes.
  • -
  • fmtime, dmtime the document file and document times.
  • -
  • xdocid the document Xapian document ID. This is useful if you -want to access the document through a direct Xapian operation.
  • -
  • mtype the document MIME type.
  • -
  • Fields stored by default: author, filename, keywords, -recipient
  • -
-

At query time, only the fields that are defined as stored either by -default or in the fields configuration file will be meaningful in -the Doc object. The document processed text may be present or not, -depending if the index stores the text at all, and if it does, on the -fetchtext query execute option. See also the rclextract module -for accessing document contents.

-
-
get(key), [] operator
-
Retrieve the named document attribute. You can also use -getattr(doc, key) or doc.key.
-
doc.key = value
-
Set the the named document attribute. You can also use -setattr(doc, key, value).
-
getbinurl()
-
Retrieve the URL in byte array format (no transcoding), for use as -parameter to a system call.
-
setbinurl(url)
-
Set the URL in byte array format (no transcoding).
-
items()
-
Return a dictionary of doc object keys/values
-
keys()
-
list of doc object keys (attribute names).
-
-

A SearchData object allows building a query by combining clauses, -for execution by Query.executesd(). It can be used in replacement of -the query language approach. The interface is going to change a little, -so no detailed doc for now...

-

addclause(type=’and’|’or’|’excl’|’phrase’|’near’|’sub’, -qstring=string, slack=0, field=’‘, stemming=1, subSearch=SearchData)

-
-
-
The rclextract module
-

Prior to RCL 1.25, index queries could not provide document content -because it was never stored. RCL 1.25 and later usually store the -document text, which can be optionally retrieved when running a query -(see query.execute() above - the result is always plain text).

-

The rclextract module can give access to the original document and -to the document text content (if not stored by the index, or to access -an HTML version of the text). Acessing the original document is -particularly useful if it is embedded (e.g. an email attachment).

-

You need to import the recoll module before the rclextract -module.

-
-
Extractor(doc)
-
An Extractor object is built from a Doc object, output from -a query.
-
Extractor.textextract(ipath)
-

Extract document defined by ipath and return a Doc object. The -doc.text field has the document text converted to either -text/plain or text/html according to doc.mimetype. The typical -use would be as follows:

-
from recoll import recoll, rclextract
-
-qdoc = query.fetchone()
-extractor = recoll.Extractor(qdoc)
-doc = extractor.textextract(qdoc.ipath)
-# use doc.text, e.g. for previewing
-
-
-

Passing qdoc.ipath to textextract() is redundant, but -reflects the fact that the Extractor object actually has the -capability to access the other entries in a compound document.

-
-
Extractor.idoctofile(ipath, targetmtype, outfile=’‘)
-

Extracts document into an output file, which can be given explicitly -or will be created as a temporary file to be deleted by the caller. -Typical use:

-
from recoll import recoll, rclextract
-
-qdoc = query.fetchone()
-extractor = recoll.Extractor(qdoc)
-filename = extractor.idoctofile(qdoc.ipath, qdoc.mimetype)
-
-
-

In all cases the output is a copy, even if the requested document is -a regular system file, which may be wasteful in some cases. If you -want to avoid this, you can test for a simple file document as -follows:

-
not doc.ipath and (not "rclbes" in doc.keys() or doc["rclbes"] == "FS")
-
-
-
-
-
-
-
Search API usage example
-

The following sample would query the index with a user language string. -See the python/samples directory inside the RCL source for other -examples. The recollgui subdirectory has a very embryonic GUI which -demonstrates the highlighting and data extraction functions.

-
#!/usr/bin/env python
-
-from recoll import recoll
-
-db = recoll.connect()
-db.setAbstractParams(maxchars=80, contextwords=4)
-
-query = db.query()
-nres = query.execute("some user question")
-print "Result count: ", nres
-if nres > 5:
-    nres = 5
-for i in range(nres):
-    doc = query.fetchone()
-    print "Result #%d" % (query.rownumber,)
-    for k in ("title", "size"):
-        print k, ":", getattr(doc, k).encode('utf-8')
-    abs = db.makeDocAbstract(doc, query).encode('utf-8')
-    print abs
-    print
-
-
-
-
-
-

Creating Python external indexers

-

The update API can be used to create an index from data which is not -accessible to the regular RCL indexer, or structured to present -difficulties to the RCL input handlers.

-

An indexer created using this API will be have equivalent work to do as -the the Recoll file system indexer: look for modified documents, extract -their text, call the API for indexing it, take care of purging the index -out of data from documents which do not exist in the document store any -more.

-

The data for such an external indexer should be stored in an index -separate from any used by the RCL internal file system indexer. The -reason is that the main document indexer purge pass (removal of deleted -documents) would also remove all the documents belonging to the external -indexer, as they were not seen during the filesystem walk. The main -indexer documents would also probably be a problem for the external -indexer own purge operation.

-

While there would be ways to enable multiple foreign indexers to -cooperate on a single index, it is just simpler to use separate ones, -and use the multiple index access capabilities of the query interface, -if needed.

-

There are two parts in the update interface:

-
    -
  • Methods inside the recoll module allow inserting data into the -index, to make it accessible by the normal query interface.
  • -
  • An interface based on scripts execution is defined to allow either -the GUI or the rclextract module to access original document data -for previewing or editing.
  • -
-
-
Python update interface
-

The update methods are part of the recoll module described above. -The connect() method is used with a writable=true parameter to -obtain a writable Db object. The following Db object methods are -then available.

-
-
addOrUpdate(udi, doc, parent_udi=None)
-
Add or update index data for a given document The udi string -must define a unique id for the document. It is an opaque interface -element and not interpreted inside Recoll. doc is a Doc -object, created from the data to be indexed (the main text should be -in doc.text). If parent_udi is set, this is a unique -identifier for the top-level container (e.g. for the filesystem -indexer, this would be the one which is an actual file).
-
delete(udi)
-
Purge index from all data for udi, and all documents (if any) -which have a matrching parent_udi.
-
needUpdate(udi, sig)
-

Test if the index needs to be updated for the document identified by -udi. If this call is to be used, the doc.sig field should -contain a signature value when calling addOrUpdate(). The -needUpdate() call then compares its parameter value with the -stored sig for udi. sig is an opaque value, compared as -a string.

-

The filesystem indexer uses a concatenation of the decimal string -values for file size and update time, but a hash of the contents -could also be used.

-

As a side effect, if the return value is false (the index is up to -date), the call will set the existence flag for the document (and -any subdocument defined by its parent_udi), so that a later -purge() call will preserve them).

-

The use of needUpdate() and purge() is optional, and the -indexer may use another method for checking the need to reindex or -to delete stale entries.

-
-
purge()
-
Delete all documents that were not touched during the just finished -indexing pass (since open-for-write). These are the documents for -the needUpdate() call was not performed, indicating that they no -longer exist in the primary storage system.
-
-
-
-
Query data access for external indexers (1.23)
-

RCL has internal methods to access document data for its internal -(filesystem) indexer. An external indexer needs to provide data access -methods if it needs integration with the GUI (e.g. preview function), or -support for the rclextract module.

-

The index data and the access method are linked by the rclbes -(recoll backend storage) Doc field. You should set this to a short -string value identifying your indexer (e.g. the filesystem indexer uses -either “FS” or an empty value, the Web history indexer uses “BGL”).

-

The link is actually performed inside a backends configuration file -(stored in the configuration directory). This defines commands to -execute to access data from the specified indexer. Example, for the mbox -indexing sample found in the Recoll source (which sets -rclbes="MBOX"):

-
[MBOX]
-          fetch = /path/to/recoll/src/python/samples/rclmbox.py fetch
-          makesig = path/to/recoll/src/python/samples/rclmbox.py makesig
-
-
-

fetch and makesig define two commands to execute to respectively -retrieve the document text and compute the document signature (the -example implementation uses the same script with different first -parameters to perform both operations).

-

The scripts are called with three additional arguments: udi, -url, ipath, stored with the document when it was indexed, and -may use any or all to perform the requested operation. The caller -expects the result data on stdout.

-
-
-
External indexer samples
-

The Recoll source tree has two samples of external indexers in the -src/python/samples directory. The more interesting one is -rclmbox.py which indexes a directory containing mbox folder -files. It exercises most features in the update interface, and has a -data access interface.

-

See the comments inside the file for more information.

-
-
-
-

Package compatibility with the previous version

-

The following code fragments can be used to ensure that code can run -with both the old and the new API (as long as it does not use the new -abilities of the new API of course).

-

Adapting to the new package structure:

-
try:
-from recoll import recoll
-from recoll import rclextract
-hasextract = True
-except:
-import recoll
-hasextract = False
-
-
-

Adapting to the change of nature of the next Query member. The -same test can be used to choose to use the scroll() method (new) or -set the next value (old).

-
rownum = query.next if type(query.next) == int else \
-query.rownumber
-
-
-
-
-
-
-

Installation and configuration

-
-

Installing a binary copy

-

RCL binary copies are always distributed as regular packages for your -system. They can be obtained either through the system’s normal software -distribution framework (e.g. Debian/Ubuntu apt, FreeBSD ports, etc.), or -from some type of “backports” repository providing versions newer than -the standard ones, or found on the RCL WEB site in some cases. The most -up-to-date information about Recoll packages can usually be found on the -Recoll WEB site downloads page

-

There used to exist another form of binary install, as pre-compiled -source trees, but these are just less convenient than the packages and -don’t exist any more.

-

The package management tools will usually automatically deal with hard -dependancies for packages obtained from a proper package repository. You -will have to deal with them by hand for downloaded packages (for -example, when dpkg complains about missing dependancies).

-

In all cases, you will have to check or install supporting -applications for the file types that you want -to index beyond those that are natively processed by RCL (text, HTML, -email files, and a few others).

-

You should also maybe have a look at the configuration -section (but this may not be necessary for a -quick test with default parameters). Most parameters can be more -conveniently set from the GUI interface.

-
-
-

Supporting packages

-
-

Note

-

The WIN installation of RCL is self-contained, and only needs Python -2.7 to be externally installed. WIN users can skip this section.

-
-

RCL uses external applications to index some file types. You need to -install them for the file types that you wish to have indexed (these are -run-time optional dependencies. None is needed for building or running -RCL except for indexing their specific file type).

-

After an indexing pass, the commands that were found missing can be -displayed from the recoll File menu. The list is stored in the -missing text file inside the configuration directory.

-

A list of common file types which need external commands follows. Many -of the handlers need the iconv command, which is not always listed -as a dependancy.

-

Please note that, due to the relatively dynamic nature of this -information, the most up to date version is now kept on RCLAPPS along -with links to the home pages or best source/patches pages, and misc -tips. The list below is not updated often and may be quite stale.

-

For many Linux distributions, most of the commands listed can be -installed from the package repositories. However, the packages are -sometimes outdated, or not the best version for RCL, so you should take -a look at RCLAPPS if a file type is important to you.

-

As of RCL release 1.14, a number of XML-based formats that were handled -by ad hoc handler code now use the xsltproc command, which usually -comes with libxslt. These are: abiword, fb2 (ebooks), kword, openoffice, -svg.

-

Now for the list:

-
    -
  • Openoffice files need unzip and xsltproc.
  • -
  • PDF files need pdftotext which is part of Poppler (usually comes -with the poppler-utils package). Avoid the original one from -Xpdf.
  • -
  • Postscript files need pstotext. The original version has an issue -with shell character in file names, which is corrected in recent -packages. See RCLAPPS for more detail.
  • -
  • MS Word needs antiword. It is also useful to have wvWare -installed as it may be be used as a fallback for some files which -antiword does not handle.
  • -
  • MS Excel and PowerPoint are processed by internal Python -handlers.
  • -
  • -
    MS Open XML (docx) needs ``
    -
    xsltproc``.
    -
    -
  • -
  • Wordperfect files need wpd2html from the libwpd (or libwpd-tools -on Ubuntu) package.
  • -
  • RTF files need unrtf, which, in its older versions, has much -trouble with non-western character sets. Many Linux distributions -carry outdated unrtf versions. Check RCLAPPS for details.
  • -
  • TeX files need untex or detex. Check RCLAPPS for sources if -it’s not packaged for your distribution.
  • -
  • dvi files need dvips.
  • -
  • djvu files need djvutxt and djvused from the DjVuLibre -package.
  • -
  • Audio files: RCL releases 1.14 and later use a single Python handler -based on mutagen for all audio file types.
  • -
  • Pictures: RCL uses the Exiftool Perl package to extract tag -information. Most image file formats are supported. Note that there -may not be much interest in indexing the technical tags (image size, -aperture, etc.). This is only of interest if you store personal tags -or textual descriptions inside the image files.
  • -
  • chm: files in Microsoft help format need Python and the pychm module -(which needs chmlib).
  • -
  • ICS: up to RCL 1.13, iCalendar files need Python and the icalendar -module. icalendar is not needed for newer versions, which use -internal code.
  • -
  • Zip archives need Python (and the standard zipfile module).
  • -
  • Rar archives need Python, the rarfile Python module and the unrar -utility.
  • -
  • Midi karaoke files need Python and the Midi -module
  • -
  • Konqueror webarchive format with Python (uses the Tarfile module).
  • -
  • Mimehtml web archive format (support based on the email handler, -which introduces some mild weirdness, but still usable).
  • -
-

Text, HTML, email folders, and Scribus files are processed internally. -Lyx is used to index Lyx files. Many handlers need iconv and the -standard sed and awk.

-
-
-

Building from source

-
-

Prerequisites

-

The following prerequisites are described in broad terms and not as -specific package names (which will depend on the exact platform). The -dependancies should be available as packages on most common Unix -derivatives, and it should be quite uncommon that you would have to -build one of them.

-

The shopping list:

-
    -
  • The autoconf, automake and libtool triad. Only -autoconf is needed for RCL 1.21 and earlier.

    -
  • -
  • C++ compiler. Recent versions require C++11 compatibility (1.23 and -later).

    -
  • -
  • bison command (for RCL 1.21 and later).

    -
  • -
  • xsltproc command. For building the documentation (for RCL 1.21 -and later). This sometimes comes with the libxslt package. And also -the Docbook XML and style sheet files.

    -
  • -
  • Development files for Xapian core.

    -
    -

    Important

    -

    If you are building Xapian for an older CPU (before Pentium 4 or -Athlon 64), you need to add the --disable-sse flag to the -configure command. Else all Xapian application will crash with an -illegal instruction error.

    -
    -
  • -
  • Development files for Qt 4 or Qt -5. RCL 1.15.9 was the last -version to support Qt 3. If you do not want to install or build the -Qt Webkit module, RCL has a configuration option to disable its use -(see further in the configuration section).

    -
  • -
  • Development files for X11 and zlib.

    -
  • -
  • Development files for Python (or use --disable-python-module).

    -
  • -
  • You may also need -libiconv. On Linux -systems, the iconv interface is part of libc and you should not need -to do anything special.

    -
  • -
-

Check the RCL download page -for up to date version information.

-
-
-

Building

-

RCL has been built on Linux, FreeBSD, Mac OS X, and Solaris, most -versions after 2005 should be ok, maybe some older ones too (Solaris 8 -is ok). If you build on another system, and need to modify things, I -would very much welcome patches.

-

Configure options:.

-
    -
  • --without-aspell will disable the code for phonetic matching of -search terms.
  • -
  • --with-fam or --with-inotify will enable the code for real -time indexing. Inotify support is enabled by default on recent Linux -systems.
  • -
  • --with-qzeitgeist will enable sending Zeitgeist events about the -visited search results, and needs the qzeitgeist package.
  • -
  • --disable-webkit is available from version 1.17 to implement the -result list with a Qt QTextBrowser instead of a WebKit widget if you -do not or can’t depend on the latter.
  • -
  • --disable-idxthreads is available from version 1.19 to suppress -multithreading inside the indexing process. You can also use the -run-time configuration to restrict recollindex to using a single -thread, but the compile-time option may disable a few more unused -locks. This only applies to the use of multithreading for the core -index processing (data input). The RCL monitor mode always uses at -least two threads of execution.
  • -
  • --disable-python-module will avoid building the Python module.
  • -
  • --disable-xattr will prevent fetching data from file extended -attributes. Beyond a few standard attributes, fetching extended -attributes data can only be useful is some application stores data in -there, and also needs some simple configuration (see comments in the -fields configuration file).
  • -
  • --enable-camelcase will enable splitting camelCase words. This is -not enabled by default as it has the unfortunate side-effect of -making some phrase searches quite confusing: ie, "MySQL manual" -would be matched by "MySQL manual" and "my sql manual" but -not "mysql manual" (only inside phrase searches).
  • -
  • --with-file-command Specify the version of the ‘file’ command to -use (ie: –with-file-command=/usr/local/bin/file). Can be useful to -enable the gnu version on systems where the native one is bad.
  • -
  • --disable-qtgui Disable the Qt interface. Will allow building the -indexer and the command line search program in absence of a Qt -environment.
  • -
  • --disable-x11mon Disable X11 connection monitoring inside -recollindex. Together with –disable-qtgui, this allows building -recoll without Qt and X11.
  • -
  • --disable-userdoc will avoid building the user manual. This -avoids having to install the Docbook XML/XSL files and the TeX -toolchain used for translating the manual to PDF.
  • -
  • --disable-pic (RCL versions up to 1.21 only) will compile RCL -with position-dependant code. This is incompatible with building the -KIO or the Python or PHP extensions, but might yield very marginally -faster code.
  • -
  • Of course the usual autoconf configure options, like --prefix -apply.
  • -
-

Normal procedure (for source extracted from a tar distribution):

-
cd recoll-xxx
-./configure
-make
-(practices usual hardship-repelling invocations)
-
-
-

When building from source cloned from the git repository, you also need -to install autoconf, automake, and libtool and you must execute -sh autogen.sh in the top source directory before running -configure.

-
-
-

Installing

-

Use make install in the root of the source tree. This will copy the -commands to prefix/bin and the sample configuration files, scripts -and other shared data to prefix/share/recoll.

-
-
-

Python API package

-

The Python interface can be found in the source tree, under the -python/recoll directory.

-

As of RCL 1.19, the module can be compiled for Python3.

-

The normal RCL build procedure (see above) installs the API package for -the default system version (python) along with the main code. The -package for other Python versions (e.g. python3 if the system default is -python2) must be explicitely built and installed.

-

The python/recoll/ directory contains the usual setup.py. After -configuring and building the main RCL code, you can use the script to -build and install the Python module:

-
cd recoll-xxx/python/recoll
-pythonX setup.py build
-sudo pythonX setup.py install
-
-
-
-
-

Building on Solaris

-

We did not test building the GUI on Solaris for recent versions. You -will need at least Qt 4.4. There are some hints on an old web site -page, they may still be -valid.

-

Someone did test the 1.19 indexer and Python module build, they do work, -with a few minor glitches. Be sure to use GNU make and install.

-
-
-
-

Configuration overview

-

Most of the parameters specific to the recoll GUI are set through -the Preferences menu and stored in the standard Qt place -($HOME/.config/Recoll.org/recoll.conf). You probably do not want to -edit this by hand.

-

RCL indexing options are set inside text configuration files located in -a configuration directory. There can be several such directories, each -of which defines the parameters for one index.

-

The configuration files can be edited by hand or through the Index -configuration dialog (Preferences menu). The GUI tool will try to -respect your formatting and comments as much as possible, so it is quite -possible to use both approaches on the same configuration.

-

The most accurate documentation for the configuration parameters is -given by comments inside the default files, and we will just give a -general overview here.

-

For each index, there are at least two sets of configuration files. -System-wide configuration files are kept in a directory named like -/usr/share/recoll/examples, and define default values, shared by all -indexes. For each index, a parallel set of files defines the customized -parameters.

-

The default location of the customized configuration is the .recoll -directory in your home. Most people will only use this directory.

-

This location can be changed, or others can be added with the -RECOLL_CONFDIR environment variable or the -c option parameter to -recoll and recollindex.

-

In addition (as of RCL version 1.19.7), it is possible to specify two -additional configuration directories which will be stacked before and -after the user configuration directory. These are defined by the -RECOLL_CONFTOP and RECOLL_CONFMID environment variables. Values from -configuration files inside the top directory will override user ones, -values from configuration files inside the middle directory will -override system ones and be overriden by user ones. These two variables -may be of use to applications which augment RCL functionality, and need -to add configuration data without disturbing the user’s files. Please -note that the two, currently single, values will probably be interpreted -as colon-separated lists in the future: do not use colon characters -inside the directory paths.

-

If the .recoll directory does not exist when recoll or -recollindex are started, it will be created with a set of empty -configuration files. recoll will give you a chance to edit the -configuration file before starting indexing. recollindex will -proceed immediately. To avoid mistakes, the automatic directory creation -will only occur for the default location, not if -c or -RECOLL_CONFDIR were used (in the latter cases, you will have to create -the directory).

-

All configuration files share the same format. For example, a short -extract of the main configuration file might look as follows:

-
# Space-separated list of files and directories to index.
-topdirs =  ~/docs /usr/share/doc
-
-[~/somedirectory-with-utf8-txt-files]
-defaultcharset = utf-8
-
-
-

There are three kinds of lines:

-
    -
  • Comment (starts with #) or empty.
  • -
  • Parameter affectation (name = value).
  • -
  • Section definition ([somedirname]).
  • -
-

Long lines can be broken by ending each incomplete part with a backslash -(\).

-

Depending on the type of configuration file, section definitions either -separate groups of parameters or allow redefining some parameters for a -directory sub-tree. They stay in effect until another section -definition, or the end of file, is encountered. Some of the parameters -used for indexing are looked up hierarchically from the current -directory location upwards. Not all parameters can be meaningfully -redefined, this is specified for each in the next section.

-
-

Important

-

Global parameters must not be defined in a directory subsection, -else they will not be found at all by the RCL code, which looks for -them at the top level (e.g. skippedPaths).

-
-

When found at the beginning of a file path, the tilde character (~) is -expanded to the name of the user’s home directory, as a shell would do.

-

Some parameters are lists of strings. White space is used for -separation. List elements with embedded spaces can be quoted using -double-quotes. Double quotes inside these elements can be escaped with a -backslash.

-

No value inside a configuration file can contain a newline character. -Long lines can be continued by escaping the physical newline with -backslash, even inside quoted strings.

-
astringlist =  "some string \
-with spaces"
-thesame = "some string with spaces"
-
-
-

Parameters which are not part of string lists can’t be quoted, and -leading and trailing space characters are stripped before the value is -used.

-

Encoding issues.

-

Most of the configuration parameters are plain ASCII. Two particular -sets of values may cause encoding issues:

-
    -
  • File path parameters may contain non-ascii characters and should use -the exact same byte values as found in the file system directory. -Usually, this means that the configuration file should use the system -default locale encoding.
  • -
  • The unac_except_trans parameter should be encoded in UTF-8. If your -system locale is not UTF-8, and you need to also specify non-ascii -file paths, this poses a difficulty because common text editors -cannot handle multiple encodings in a single file. In this relatively -unlikely case, you can edit the configuration file as two separate -text files with appropriate encodings, and concatenate them to create -the complete configuration.
  • -
-
-

Environment variables

-
-
RECOLL_CONFDIR
-
Defines the main configuration directory.
-
RECOLL_TMPDIR, TMPDIR
-
Locations for temporary files, in this order of priority. The -default if none of these is set is to use /tmp. Big temporary -files may be created during indexing, mostly for decompressing, and -also for processing, e.g. email attachments.
-
RECOLL_CONFTOP, RECOLL_CONFMID
-
Allow adding configuration directories with priorities below and -above the user directory (see above the Configuration overview -section for details).
-
RECOLL_EXTRA_DBS, RECOLL_ACTIVE_EXTRA_DBS
-
Help for setting up external indexes. See this -paragraph for explanations.
-
RECOLL_DATADIR
-
Defines replacement for the default location of Recoll data files, -normally found in, e.g., /usr/share/recoll).
-
RECOLL_FILTERSDIR
-
Defines replacement for the default location of Recoll filters, -normally found in, e.g., /usr/share/recoll/filters).
-
ASPELL_PROG
-
aspell program to use for creating the spelling dictionary. The -result has to be compatible with the libaspell which RCL is -using.
-
VARNAME
-
Blabla
-
-
-
-

Recoll main configuration file, recoll.conf

-
-
Parameters affecting what documents we index
-
-
topdirs
-
Space-separated list of files or directories to recursively index. -Default to ~ (indexes $HOME). You can use symbolic links in the -list, they will be followed, independantly of the value of the -followLinks variable.
-
monitordirs
-
Space-separated list of files or directories to monitor for updates. -When running the real-time indexer, this allows monitoring only a -subset of the whole indexed area. The elements must be included in -the tree defined by the ‘topdirs’ members.
-
skippedNames
-
Files and directories which should be ignored. White space separated -list of wildcard patterns (simple ones, not paths, must contain no / -), which will be tested against file and directory names. The list -in the default configuration does not exclude hidden directories -(names beginning with a dot), which means that it may index quite a -few things that you do not want. On the other hand, email user -agents like Thunderbird usually store messages in hidden -directories, and you probably want this indexed. One possible -solution is to have ”.*” in “skippedNames”, and add things like -“~/.thunderbird” “~/.evolution” to “topdirs”. Not even the file -names are indexed for patterns in this list, see the -“noContentSuffixes” variable for an alternative approach which -indexes the file names. Can be redefined for any subtree.
-
skippedNames-
-
List of name endings to remove from the default skippedNames list.
-
skippedNames+
-
List of name endings to add to the default skippedNames list.
-
noContentSuffixes
-
List of name endings (not necessarily dot-separated suffixes) for -which we don’t try MIME type identification, and don’t uncompress or -index content. Only the names will be indexed. This complements the -now obsoleted recoll_noindex list from the mimemap file, which will -go away in a future release (the move from mimemap to recoll.conf -allows editing the list through the GUI). This is different from -skippedNames because these are name ending matches only (not -wildcard patterns), and the file name itself gets indexed normally. -This can be redefined for subdirectories.
-
noContentSuffixes-
-
List of name endings to remove from the default noContentSuffixes -list.
-
noContentSuffixes+
-
List of name endings to add to the default noContentSuffixes list.
-
skippedPaths
-
Absolute paths we should not go into. Space-separated list of -wildcard expressions for absolute filesystem paths. Must be defined -at the top level of the configuration file, not in a subsection. Can -contain files and directories. The database and configuration -directories will automatically be added. The expressions are matched -using ‘fnmatch(3)’ with the FNM_PATHNAME flag set by default. This -means that ‘/’ characters must be matched explicitely. You can set -‘skippedPathsFnmPathname’ to 0 to disable the use of FNM_PATHNAME -(meaning that ‘/*/dir3’ will match ‘/dir1/dir2/dir3’). The default -value contains the usual mount point for removable media to remind -you that it is a bad idea to have Recoll work on these (esp. with -the monitor: media gets indexed on mount, all data gets erased on -unmount). Explicitely adding ‘/media/xxx’ to the ‘topdirs’ variable -will override this.
-
skippedPathsFnmPathname
-
Set to 0 to override use of FNM_PATHNAME for matching skipped -paths.
-
nowalkfn
-
File name which will cause its parent directory to be skipped. Any -directory containing a file with this name will be skipped as if it -was part of the skippedPaths list. Ex: .recoll-noindex
-
daemSkippedPaths
-
skippedPaths equivalent specific to real time indexing. This enables -having parts of the tree which are initially indexed but not -monitored. If daemSkippedPaths is not set, the daemon uses -skippedPaths.
-
zipUseSkippedNames
-
Use skippedNames inside Zip archives. Fetched directly by the rclzip -handler. Skip the patterns defined by skippedNames inside Zip -archives. Can be redefined for subdirectories. See -https://www.lesbonscomptes.com/recoll/faqsandhowtos/FilteringOutZipArchiveMembers.html
-
zipSkippedNames
-
Space-separated list of wildcard expressions for names that should -be ignored inside zip archives. This is used directly by the zip -handler. If zipUseSkippedNames is not set, zipSkippedNames defines -the patterns to be skipped inside archives. If zipUseSkippedNames is -set, the two lists are concatenated and used. Can be redefined for -subdirectories. See -https://www.lesbonscomptes.com/recoll/faqsandhowtos/FilteringOutZipArchiveMembers.html
-
followLinks
-
Follow symbolic links during indexing. The default is to ignore -symbolic links to avoid multiple indexing of linked files. No effort -is made to avoid duplication when this option is set to true. This -option can be set individually for each of the ‘topdirs’ members by -using sections. It can not be changed below the ‘topdirs’ level. -Links in the ‘topdirs’ list itself are always followed.
-
indexedmimetypes
-
Restrictive list of indexed mime types. Normally not set (in which -case all supported types are indexed). If it is set, only the types -from the list will have their contents indexed. The names will be -indexed anyway if indexallfilenames is set (default). MIME type -names should be taken from the mimemap file (the values may be -different from xdg-mime or file -i output in some cases). Can be -redefined for subtrees.
-
excludedmimetypes
-
List of excluded MIME types. Lets you exclude some types from -indexing. MIME type names should be taken from the mimemap file (the -values may be different from xdg-mime or file -i output in some -cases) Can be redefined for subtrees.
-
nomd5types
-
Don’t compute md5 for these types. md5 checksums are used only for -deduplicating results, and can be very expensive to compute on -multimedia or other big files. This list lets you turn off md5 -computation for selected types. It is global (no redefinition for -subtrees). At the moment, it only has an effect for external -handlers (exec and execm). The file types can be specified by -listing either MIME types (e.g. audio/mpeg) or handler names (e.g. -rclaudio).
-
compressedfilemaxkbs
-
Size limit for compressed files. We need to decompress these in a -temporary directory for identification, which can be wasteful in -some cases. Limit the waste. Negative means no limit. 0 results in -no processing of any compressed file. Default 50 MB.
-
textfilemaxmbs
-
Size limit for text files. Mostly for skipping monster logs. Default -20 MB.
-
indexallfilenames
-
Index the file names of unprocessed files Index the names of files -the contents of which we don’t index because of an excluded or -unsupported MIME type.
-
usesystemfilecommand
-
Use a system command for file MIME type guessing as a final step in -file type identification This is generally useful, but will usually -cause the indexing of many bogus ‘text’ files. See -‘systemfilecommand’ for the command used.
-
systemfilecommand
-
Command used to guess MIME types if the internal methods fails This -should be a “file -i” workalike. The file path will be added as a -last parameter to the command line. ‘xdg-mime’ works better than the -traditional ‘file’ command, and is now the configured default (with -a hard-coded fallback to ‘file’)
-
processwebqueue
-
Decide if we process the Web queue. The queue is a directory where -the Recoll Web browser plugins create the copies of visited pages.
-
textfilepagekbs
-
Page size for text files. If this is set, text/plain files will be -divided into documents of approximately this size. Will reduce -memory usage at index time and help with loading data in the preview -window at query time. Particularly useful with very big files, such -as application or system logs. Also see textfilemaxmbs and -compressedfilemaxkbs.
-
membermaxkbs
-
Size limit for archive members. This is passed to the filters in the -environment as RECOLL_FILTER_MAXMEMBERKB.
-
-
-
-
Parameters affecting how we generate terms and organize the index
-
-
indexStripChars
-
Decide if we store character case and diacritics in the index. If we -do, searches sensitive to case and diacritics can be performed, but -the index will be bigger, and some marginal weirdness may sometimes -occur. The default is a stripped index. When using multiple indexes -for a search, this parameter must be defined identically for all. -Changing the value implies an index reset.
-
indexStoreDocText
-
Decide if we store the documents’ text content in the index. Storing -the text allows extracting snippets from it at query time, instead -of building them from index position data. Newer Xapian index -formats have rendered our use of positions list unacceptably slow in -some cases. The last Xapian index format with good performance for -the old method is Chert, which is default for 1.2, still supported -but not default in 1.4 and will be dropped in 1.6. The stored -document text is translated from its original format to UTF-8 plain -text, but not stripped of upper-case, diacritics, or punctuation -signs. Storing it increases the index size by 10-20% typically, but -also allows for nicer snippets, so it may be worth enabling it even -if not strictly needed for performance if you can afford the space. -The variable only has an effect when creating an index, meaning that -the xapiandb directory must not exist yet. Its exact effect depends -on the Xapian version. For Xapian 1.4, if the variable is set to 0, -the Chert format will be used, and the text will not be stored. If -the variable is 1, Glass will be used, and the text stored. For -Xapian 1.2, and for versions after 1.5 and newer, the index format -is always the default, but the variable controls if the text is -stored or not, and the abstract generation method. With Xapian 1.5 -and later, and the variable set to 0, abstract generation may be -very slow, but this setting may still be useful to save space if you -do not use abstract generation at all.
-
nonumbers
-
Decides if terms will be generated for numbers. For example “123”, -“1.5e6”, 192.168.1.4, would not be indexed if nonumbers is set -(“value123” would still be). Numbers are often quite interesting to -search for, and this should probably not be set except for special -situations, ie, scientific documents with huge amounts of numbers in -them, where setting nonumbers will reduce the index size. This can -only be set for a whole index, not for a subtree.
-
dehyphenate
-
Determines if we index ‘coworker’ also when the input is -‘co-worker’. This is new in version 1.22, and on by default. Setting -the variable to off allows restoring the previous behaviour.
-
backslashasletter
-
Process backslash as normal letter This may make sense for people -wanting to index TeX commands as such but is not of much general -use.
-
maxtermlength
-
Maximum term length. Words longer than this will be discarded. The -default is 40 and used to be hard-coded, but it can now be adjusted. -You need an index reset if you change the value.
-
nocjk
-
Decides if specific East Asian (Chinese Korean Japanese) -characters/word splitting is turned off. This will save a small -amount of CPU if you have no CJK documents. If your document base -does include such text but you are not interested in searching it, -setting nocjk may be a significant time and space saver.
-
cjkngramlen
-
This lets you adjust the size of n-grams used for indexing CJK text. -The default value of 2 is probably appropriate in most cases. A -value of 3 would allow more precision and efficiency on longer -words, but the index will be approximately twice as large.
-
indexstemminglanguages
-
Languages for which to create stemming expansion data. Stemmer names -can be found by executing ‘recollindex -l’, or this can also be set -from a list in the GUI.
-
defaultcharset
-
Default character set. This is used for files which do not contain a -character set definition (e.g.: text/plain). Values found inside -files, e.g. a ‘charset’ tag in HTML documents, will override it. If -this is not set, the default character set is the one defined by the -NLS environment ($LC_ALL, $LC_CTYPE, $LANG), or ultimately -iso-8859-1 (cp-1252 in fact). If for some reason you want a general -default which does not match your LANG and is not 8859-1, use this -variable. This can be redefined for any sub-directory.
-
unac_except_trans
-
A list of characters, encoded in UTF-8, which should be handled -specially when converting text to unaccented lowercase. For example, -in Swedish, the letter a with diaeresis has full alphabet -citizenship and should not be turned into an a. Each element in the -space-separated list has the special character as first element and -the translation following. The handling of both the lowercase and -upper-case versions of a character should be specified, as -appartenance to the list will turn-off both standard accent and case -processing. The value is global and affects both indexing and -querying. Examples: Swedish: unac_except_trans = ää Ää öö Öö üü Üü -ßss œoe Œoe æae Æae ffff fifi flfl åå Åå . German: unac_except_trans -= ää Ää öö Öö üü Üü ßss œoe Œoe æae Æae ffff fifi flfl In French, you -probably want to decompose oe and ae and nobody would type a German -ß unac_except_trans = ßss œoe Œoe æae Æae ffff fifi flfl . The -default for all until someone protests follows. These decompositions -are not performed by unac, but it is unlikely that someone would -type the composed forms in a search. unac_except_trans = ßss œoe -Œoe æae Æae ffff fifi flfl
-
maildefcharset
-
Overrides the default character set for email messages which don’t -specify one. This is mainly useful for readpst (libpst) dumps, which -are utf-8 but do not say so.
-
localfields
-
Set fields on all files (usually of a specific fs area). Syntax is -the usual: name = value ; attr1 = val1 ; [...] value is empty so -this needs an initial semi-colon. This is useful, e.g., for setting -the rclaptg field for application selection inside mimeview.
-
testmodifusemtime
-
Use mtime instead of ctime to test if a file has been modified. The -time is used in addition to the size, which is always used. Setting -this can reduce re-indexing on systems where extended attributes are -used (by some other application), but not indexed, because changing -extended attributes only affects ctime. Notes: - This may prevent -detection of change in some marginal file rename cases (the target -would need to have the same size and mtime). - You should probably -also set noxattrfields to 1 in this case, except if you still prefer -to perform xattr indexing, for example if the local file update -pattern makes it of value (as in general, there is a risk for pure -extended attributes updates without file modification to go -undetected). Perform a full index reset after changing this.
-
noxattrfields
-
Disable extended attributes conversion to metadata fields. This -probably needs to be set if testmodifusemtime is set.
-
metadatacmds
-
Define commands to gather external metadata, e.g. tmsu tags. There -can be several entries, separated by semi-colons, each defining -which field name the data goes into and the command to use. Don’t -forget the initial semi-colon. All the field names must be -different. You can use aliases in the “field” file if necessary. As -a not too pretty hack conceded to convenience, any field name -beginning with “rclmulti” will be taken as an indication that the -command returns multiple field values inside a text blob formatted -as a recoll configuration file (“fieldname = fieldvalue” lines). The -rclmultixx name will be ignored, and field names and values will be -parsed from the data. Example: metadatacmds = ; tags = tmsu tags %f; -rclmulti1 = cmdOutputsConf %f
-
-
-
-
Parameters affecting where and how we store things
-
-
cachedir
-
Top directory for Recoll data. Recoll data directories are normally -located relative to the configuration directory (e.g. -~/.recoll/xapiandb, ~/.recoll/mboxcache). If ‘cachedir’ is set, the -directories are stored under the specified value instead (e.g. if -cachedir is ~/.cache/recoll, the default dbdir would be -~/.cache/recoll/xapiandb). This affects dbdir, webcachedir, -mboxcachedir, aspellDicDir, which can still be individually -specified to override cachedir. Note that if you have multiple -configurations, each must have a different cachedir, there is no -automatic computation of a subpath under cachedir.
-
maxfsoccuppc
-
Maximum file system occupation over which we stop indexing. The -value is a percentage, corresponding to what the “Capacity” df -output column shows. The default value is 0, meaning no checking.
-
dbdir
-
Xapian database directory location. This will be created on first -indexing. If the value is not an absolute path, it will be -interpreted as relative to cachedir if set, or the configuration -directory (-c argument or $RECOLL_CONFDIR). If nothing is -specified, the default is then ~/.recoll/xapiandb/
-
idxstatusfile
-
Name of the scratch file where the indexer process updates its -status. Default: idxstatus.txt inside the configuration directory.
-
mboxcachedir
-
Directory location for storing mbox message offsets cache files. -This is normally ‘mboxcache’ under cachedir if set, or else under -the configuration directory, but it may be useful to share a -directory between different configurations.
-
mboxcacheminmbs
-
Minimum mbox file size over which we cache the offsets. There is -really no sense in caching offsets for small files. The default is 5 -MB.
-
webcachedir
-
Directory where we store the archived web pages. This is only used -by the web history indexing code Default: cachedir/webcache if -cachedir is set, else $RECOLL_CONFDIR/webcache
-
webcachemaxmbs
-
Maximum size in MB of the Web archive. This is only used by the web -history indexing code. Default: 40 MB. Reducing the size will not -physically truncate the file.
-
webqueuedir
-
The path to the Web indexing queue. This used to be hard-coded in -the old plugin as ~/.recollweb/ToIndex so there would be no need or -possibility to change it, but the WebExtensions plugin now downloads -the files to the user Downloads directory, and a script moves them -to webqueuedir. The script reads this value from the config so it -has become possible to change it.
-
webdownloadsdir
-
The path to browser downloads directory. This is where the new -browser add-on extension has to create the files. They are then -moved by a script to webqueuedir.
-
aspellDicDir
-
Aspell dictionary storage directory location. The aspell dictionary -(aspdict.(lang).rws) is normally stored in the directory specified -by cachedir if set, or under the configuration directory.
-
filtersdir
-
Directory location for executable input handlers. If -RECOLL_FILTERSDIR is set in the environment, we use it instead. -Defaults to $prefix/share/recoll/filters. Can be redefined for -subdirectories.
-
iconsdir
-
Directory location for icons. The only reason to change this would -be if you want to change the icons displayed in the result list. -Defaults to $prefix/share/recoll/images
-
-
-
-
Parameters affecting indexing performance and resource usage
-
-
idxflushmb
-
Threshold (megabytes of new data) where we flush from memory to disk -index. Setting this allows some control over memory usage by the -indexer process. A value of 0 means no explicit flushing, which lets -Xapian perform its own thing, meaning flushing every -$XAPIAN_FLUSH_THRESHOLD documents created, modified or deleted: as -memory usage depends on average document size, not only document -count, the Xapian approach is is not very useful, and you should let -Recoll manage the flushes. The program compiled value is 0. The -configured default value (from this file) is now 50 MB, and should -be ok in many cases. You can set it as low as 10 to conserve memory, -but if you are looking for maximum speed, you may want to experiment -with values between 20 and 200. In my experience, values beyond this -are always counterproductive. If you find otherwise, please drop me -a note.
-
filtermaxseconds
-
Maximum external filter execution time in seconds. Default 1200 -(20mn). Set to 0 for no limit. This is mainly to avoid infinite -loops in postscript files (loop.ps)
-
filtermaxmbytes
-
Maximum virtual memory space for filter processes -(setrlimit(RLIMIT_AS)), in megabytes. Note that this includes any -mapped libs (there is no reliable Linux way to limit the data space -only), so we need to be a bit generous here. Anything over 2000 will -be ignored on 32 bits machines.
-
thrQSizes
-
Stage input queues configuration. There are three internal queues in -the indexing pipeline stages (file data extraction, terms -generation, index update). This parameter defines the queue depths -for each stage (three integer values). If a value of -1 is given for -a given stage, no queue is used, and the thread will go on -performing the next stage. In practise, deep queues have not been -shown to increase performance. Default: a value of 0 for the first -queue tells Recoll to perform autoconfiguration based on the -detected number of CPUs (no need for the two other values in this -case). Use thrQSizes = -1 -1 -1 to disable multithreading entirely.
-
thrTCounts
-
Number of threads used for each indexing stage. The three stages -are: file data extraction, terms generation, index update). The use -of the counts is also controlled by some special values in -thrQSizes: if the first queue depth is 0, all counts are ignored -(autoconfigured); if a value of -1 is used for a queue depth, the -corresponding thread count is ignored. It makes no sense to use a -value other than 1 for the last stage because updating the Xapian -index is necessarily single-threaded (and protected by a mutex).
-
-
-
-
Miscellaneous parameters
-
-
loglevel
-
Log file verbosity 1-6. A value of 2 will print only errors and -warnings. 3 will print information like document updates, 4 is quite -verbose and 6 very verbose.
-
logfilename
-
Log file destination. Use ‘stderr’ (default) to write to the -console.
-
idxloglevel
-
Override loglevel for the indexer.
-
idxlogfilename
-
Override logfilename for the indexer.
-
daemloglevel
-
Override loglevel for the indexer in real time mode. The default is -to use the idx... values if set, else the log... values.
-
daemlogfilename
-
Override logfilename for the indexer in real time mode. The default -is to use the idx... values if set, else the log... values.
-
orgidxconfdir
-
Original location of the configuration directory. This is used -exclusively for movable datasets. Locating the configuration -directory inside the directory tree makes it possible to provide -automatic query time path translations once the data set has moved -(for example, because it has been mounted on another location).
-
curidxconfdir
-
Current location of the configuration directory. Complement -orgidxconfdir for movable datasets. This should be used if the -configuration directory has been copied from the dataset to another -location, either because the dataset is readonly and an r/w copy is -desired, or for performance reasons. This records the original moved -location before copy, to allow path translation computations. For -example if a dataset originally indexed as ‘/home/me/mydata/config’ -has been mounted to ‘/media/me/mydata’, and the GUI is running from -a copied configuration, orgidxconfdir would be -‘/home/me/mydata/config’, and curidxconfdir (as set in the copied -configuration) would be ‘/media/me/mydata/config’.
-
idxrundir
-
Indexing process current directory. The input handlers sometimes -leave temporary files in the current directory, so it makes sense to -have recollindex chdir to some temporary directory. If the value is -empty, the current directory is not changed. If the value is -(literal) tmp, we use the temporary directory as set by the -environment (RECOLL_TMPDIR else TMPDIR else /tmp). If the value is -an absolute path to a directory, we go there.
-
checkneedretryindexscript
-
Script used to heuristically check if we need to retry indexing -files which previously failed. The default script checks the -modified dates on /usr/bin and /usr/local/bin. A relative path will -be looked up in the filters dirs, then in the path. Use an absolute -path to do otherwise.
-
recollhelperpath
-
Additional places to search for helper executables. This is only -used on Windows for now.
-
idxabsmlen
-
Length of abstracts we store while indexing. Recoll stores an -abstract for each indexed file. The text can come from an actual -‘abstract’ section in the document or will just be the beginning of -the document. It is stored in the index so that it can be displayed -inside the result lists without decoding the original file. The -idxabsmlen parameter defines the size of the stored abstract. The -default value is 250 bytes. The search interface gives you the -choice to display this stored text or a synthetic abstract built by -extracting text around the search terms. If you always prefer the -synthetic abstract, you can reduce this value and save a little -space.
-
idxmetastoredlen
-
Truncation length of stored metadata fields. This does not affect -indexing (the whole field is processed anyway), just the amount of -data stored in the index for the purpose of displaying fields inside -result lists or previews. The default value is 150 bytes which may -be too low if you have custom fields.
-
idxtexttruncatelen
-
Truncation length for all document texts. Only index the beginning -of documents. This is not recommended except if you are sure that -the interesting keywords are at the top and have severe disk space -issues.
-
aspellLanguage
-
Language definitions to use when creating the aspell dictionary. The -value must match a set of aspell language definition files. You can -type “aspell dicts” to see a list The default if this is not set is -to use the NLS environment to guess the value.
-
aspellAddCreateParam
-
Additional option and parameter to aspell dictionary creation -command. Some aspell packages may need an additional option (e.g. on -Debian Jessie: –local-data-dir=/usr/lib/aspell). See Debian bug -772415.
-
aspellKeepStderr
-
Set this to have a look at aspell dictionary creation errors. There -are always many, so this is mostly for debugging.
-
noaspell
-
Disable aspell use. The aspell dictionary generation takes time, and -some combinations of aspell version, language, and local terms, -result in aspell crashing, so it sometimes makes sense to just -disable the thing.
-
monauxinterval
-
Auxiliary database update interval. The real time indexer only -updates the auxiliary databases (stemdb, aspell) periodically, -because it would be too costly to do it for every document change. -The default period is one hour.
-
monixinterval
-
Minimum interval (seconds) between processings of the indexing -queue. The real time indexer does not process each event when it -comes in, but lets the queue accumulate, to diminish overhead and to -aggregate multiple events affecting the same file. Default 30 S.
-
mondelaypatterns
-
Timing parameters for the real time indexing. Definitions for files -which get a longer delay before reindexing is allowed. This is for -fast-changing files, that should only be reindexed once in a while. -A list of wildcardPattern:seconds pairs. The patterns are matched -with fnmatch(pattern, path, 0) You can quote entries containing -white space with double quotes (quote the whole entry, not the -pattern). The default is empty. Example: mondelaypatterns = -*.log:20 “*with spaces.*:30”
-
monioniceclass
-
ionice class for the real time indexing process On platforms where -this is supported. The default value is 3.
-
monioniceclassdata
-
ionice class parameter for the real time indexing process. On -platforms where this is supported. The default is empty.
-
-
-
-
Query-time parameters (no impact on the index)
-
-
autodiacsens
-
auto-trigger diacritics sensitivity (raw index only). IF the index -is not stripped, decide if we automatically trigger diacritics -sensitivity if the search term has accented characters (not in -unac_except_trans). Else you need to use the query language and -the “D” modifier to specify diacritics sensitivity. Default is no.
-
autocasesens
-
auto-trigger case sensitivity (raw index only). IF the index is not -stripped (see indexStripChars), decide if we automatically trigger -character case sensitivity if the search term has upper-case -characters in any but the first position. Else you need to use the -query language and the “C” modifier to specify character-case -sensitivity. Default is yes.
-
maxTermExpand
-
Maximum query expansion count for a single term (e.g.: when using -wildcards). This only affects queries, not indexing. We used to not -limit this at all (except for filenames where the limit was too low -at 1000), but it is unreasonable with a big index. Default 10000.
-
maxXapianClauses
-
Maximum number of clauses we add to a single Xapian query. This only -affects queries, not indexing. In some cases, the result of term -expansion can be multiplicative, and we want to avoid eating all the -memory. Default 50000.
-
snippetMaxPosWalk
-
Maximum number of positions we walk while populating a snippet for -the result list. The default of 1,000,000 may be insufficient for -very big documents, the consequence would be snippets with possibly -meaning-altering missing words.
-
-
-
-
Parameters for the PDF input script
-
-
pdfocr
-
Attempt OCR of PDF files with no text content if both tesseract and -pdftoppm are installed. The default is off because OCR is so very -slow.
-
pdfocrlang
-
Language to assume for PDF OCR. This is very important for having a -reasonable rate of errors with tesseract. This can also be set -through a configuration variable or directory-local parameters. See -the rclpdf.py script.
-
pdfattach
-
Enable PDF attachment extraction by executing pdftk (if available). -This is normally disabled, because it does slow down PDF indexing a -bit even if not one attachment is ever found.
-
pdfextrameta
-
Extract text from selected XMP metadata tags. This is a -space-separated list of qualified XMP tag names. Each element can -also include a translation to a Recoll field name, separated by a -‘|’ character. If the second element is absent, the tag name is -used as the Recoll field names. You will also need to add -specifications to the ‘fields’ file to direct processing of the -extracted data.
-
pdfextrametafix
-
Define name of XMP field editing script. This defines the name of a -script to be loaded for editing XMP field values. The script should -define a ‘MetaFixer’ class with a metafix() method which will be -called with the qualified tag name and value of each selected field, -for editing or erasing. A new instance is created for each document, -so that the object can keep state for, e.g. eliminating duplicate -values.
-
-
-
-
Parameters set for specific locations
-
-
mhmboxquirks
-
Enable thunderbird/mozilla-seamonkey mbox format quirks Set this for -the directory where the email mbox files are stored.
-
-
-
-
-

The fields file

-

This file contains information about dynamic fields handling in RCL. -Some very basic fields have hard-wired behaviour, and, mostly, you -should not change the original data inside the fields file. But you -can create custom fields fitting your data and handle them just like -they were native ones.

-

The fields file has several sections, which each define an aspect of -fields processing. Quite often, you’ll have to modify several sections -to obtain the desired behaviour.

-

We will only give a short description here, you should refer to the -comments inside the default file for more detailed information.

-

Field names should be lowercase alphabetic ASCII.

-
-
[prefixes]
-
A field becomes indexed (searchable) by having a prefix defined in -this section. There is a more complete explanation of what prefixes -are in used by a standard recoll installation. In a nutshell: -extension prefixes should be all caps, begin with XY, and short. -E.g. XYMFLD.
-
[values]
-
Fields listed in this section will be stored as XAP values -inside the index. This makes them available for range queries, -allowing to filter results according to the field value. This -feature currently supports string and integer data. See the comments -in the file for more detail
-
[stored]
-
A field becomes stored (displayable inside results) by having its -name listed in this section (typically with an empty value).
-
[aliases]
-
This section defines lists of synonyms for the canonical names used -inside the [prefixes] and [stored] sections
-
[queryaliases]
-
This section also defines aliases for the canonic field names, with -the difference that the substitution will only be used at query -time, avoiding any possibility that the value would pick-up random -metadata from documents.
-
handler-specific sections
-
Some input handlers may need specific configuration for handling -fields. Only the email message handler currently has such a section -(named [mail]). It allows indexing arbitrary email headers in -addition to the ones indexed by default. Other such sections may -appear in the future.
-
-

Here follows a small example of a personal fields file. This would -extract a specific email header and use it as a searchable field, with -data displayable inside result lists. (Side note: as the email handler -does no decoding on the values, only plain ascii headers can be indexed, -and only the first occurrence will be used for headers that occur -several times).

-
[prefixes]
-        # Index mailmytag contents (with the given prefix)
-        mailmytag = XMTAG
-
-        [stored]
-        # Store mailmytag inside the document data record (so that it can be
-        # displayed - as %(mailmytag) - in result lists).
-        mailmytag =
-
-        [queryaliases]
-        filename = fn
-        containerfilename = cfn
-
-        [mail]
-        # Extract the X-My-Tag mail header, and use it internally with the
-        # mailmytag field name
-        x-my-tag = mailmytag
-
-
-
-
Extended attributes in the fields file
-

RCL versions 1.19 and later process user extended file attributes as -documents fields by default.

-

Attributes are processed as fields of the same name, after removing the -user prefix on Linux.

-

The [xattrtofields] section of the fields file allows specifying -translations from extended attributes names to RCL field names. An empty -translation disables use of the corresponding attribute data.

-
-
-
-

The mimemap file

-

mimemap specifies the file name extension to MIME type mappings.

-

For file names without an extension, or with an unknown one, a system -command (file -i, or xdg-mime) will be executed to determine -the MIME type (this can be switched off, or the command changed inside -the main configuration file).

-

All extension values in mimemap must be entered in lower case. File -names extensions are lower-cased for comparison during indexing, meaning -that an upper case mimemap entry will never be matched.

-

The mappings can be specified on a per-subtree basis, which may be -useful in some cases. Example: okular notes have a .xml extension -but should be handled specially, which is possible because they are -usually all located in one place. Example:

-
[~/.kde/share/apps/okular/docdata]
-        .xml = application/x-okular-notes
-
-
-

The recoll_noindex mimemap variable has been moved to -recoll.conf and renamed to noContentSuffixes, while keeping the -same function, as of RCL version 1.21. For older RCL versions, see the -documentation for noContentSuffixes but use recoll_noindex in -mimemap.

-
-
-

The mimeconf file

-

The main purpose of the mimeconf file is to specify how the -different MIME types are handled for indexing. This is done in the -[index] section, which should not be modified casually. See the -comments in the file.

-

The file also contains other definitions which affect the query language -and the GUI, and which, in retrospect, should have been stored -elsewhere.

-

The [icons] section allows you to change the icons which are -displayed by the recoll GUI in the result lists (the values are the -basenames of the png images inside the iconsdir directory (which -is itself defined in recoll.conf).

-

The [categories] section defines the groupings of MIME types into -categories as used when adding an rclcat clause to a query -language query. rclcat clauses are also used -by the default guifilters buttons in the GUI (see next).

-

The filter controls appear at the top of the recoll GUI, either as -checkboxes just above the result list, or as a dropbox in the tool area.

-

By default, they are labeled: media, message, other, -presentation, spreadsheet and text, and each maps to a -document category. This is determined in the [guifilters] section, -where each control is defined by a variable naming a query language -fragment.

-

A simple exemple will hopefully make things clearer.

-
[guifilters]
-
-Big Books = dir:"~/My Books" size>10K
-My Docs = dir:"~/My Documents"
-Small Books = dir:"~/My Books" size<10K
-System Docs = dir:/usr/share/doc
-
-
-

The above definition would create four filter checkboxes, labelled -Big Books, My Docs, etc.

-

The text after the equal sign must be a valid query language fragment, -and, when the button is checked, it will be combined with the rest of -the query with an AND conjunction.

-

Any name text before a colon character will be erased in the display, -but used for sorting. You can use this to display the checkboxes in any -order you like. For exemple, the following would do exactly the same as -above, but ordering the checkboxes in the reverse order.

-
[guifilters]
-
-d:Big Books = dir:"~/My Books" size>10K
-c:My Docs = dir:"~/My Documents"
-b:Small Books = dir:"~/My Books" size<10K
-a:System Docs = dir:/usr/share/doc
-
-
-

As you may have guessed, The default [guifilters] section looks -like:

-
[guifilters]
-text = rclcat:text
-spreadsheet = rclcat:spreadsheet
-presentation = rclcat:presentation
-media = rclcat:media
-message = rclcat:message
-other = rclcat:other
-
-
-
-
-

The mimeview file

-

mimeview specifies which programs are started when you click on an -Open link in a result list. Ie: HTML is normally displayed using -firefox, but you may prefer Konqueror, your openoffice.org program might -be named oofice instead of openoffice etc.

-

Changes to this file can be done by direct editing, or through the -recoll GUI preferences dialog.

-

If Use desktop preferences to choose document editor is checked in the -RCL GUI preferences, all mimeview entries will be ignored except the -one labelled application/x-all (which is set to use xdg-open by -default).

-

In this case, the xallexcepts top level variable defines a list of -MIME type exceptions which will be processed according to the local -entries instead of being passed to the desktop. This is so that specific -RCL options such as a page number or a search string can be passed to -applications that support them, such as the evince viewer.

-

As for the other configuration files, the normal usage is to have a -mimeview inside your own configuration directory, with just the -non-default entries, which will override those from the central -configuration file.

-

All viewer definition entries must be placed under a [view] section.

-

The keys in the file are normally MIME types. You can add an application -tag to specialize the choice for an area of the filesystem (using a -localfields specification in mimeconf). The syntax for the key -is mimetype|tag

-

The nouncompforviewmts entry, (placed at the top level, outside of -the [view] section), holds a list of MIME types that should not be -uncompressed before starting the viewer (if they are found compressed, -ie: mydoc.doc.gz).

-

The right side of each assignment holds a command to be executed for -opening the file. The following substitutions are performed:

-
    -
  • %D.

    -

    Document date

    -
  • -
  • %f.

    -

    File name. This may be the name of a temporary file if it was -necessary to create one (ie: to extract a subdocument from a -container).

    -
  • -
  • %i.

    -

    Internal path, for subdocuments of containers. The format depends on -the container type. If this appears in the command line, RCL will not -create a temporary file to extract the subdocument, expecting the -called application (possibly a script) to be able to handle it.

    -
  • -
  • %M.

    -

    MIME type

    -
  • -
  • %p.

    -

    Page index. Only significant for a subset of document types, -currently only PDF, Postscript and DVI files. Can be used to start -the editor at the right page for a match or snippet.

    -
  • -
  • %s.

    -

    Search term. The value will only be set for documents with indexed -page numbers (ie: PDF). The value will be one of the matched search -terms. It would allow pre-setting the value in the “Find” entry -inside Evince for example, for easy highlighting of the term.

    -
  • -
  • %u.

    -

    Url.

    -
  • -
-

In addition to the predefined values above, all strings like -%(fieldname) will be replaced by the value of the field named -fieldname for the document. This could be used in combination with -field customisation to help with opening the document.

-
-
-

The ptrans file

-

ptrans specifies query-time path translations. These can be useful -in multiple cases.

-

The file has a section for any index which needs translations, either -the main one or additional query indexes. The sections are named with -the XAP index directory names. No slash character should exist at the -end of the paths (all comparisons are textual). An exemple should make -things sufficiently clear

-
[/home/me/.recoll/xapiandb]
-/this/directory/moved = /to/this/place
-
-[/path/to/additional/xapiandb]
-/server/volume1/docdir = /net/server/volume1/docdir
-/server/volume2/docdir = /net/server/volume2/docdir
-
-
-
-
-

Examples of configuration adjustments

-
-
Adding an external viewer for an non-indexed type
-

Imagine that you have some kind of file which does not have indexable -content, but for which you would like to have a functional Open link in -the result list (when found by file name). The file names end in .blob -and can be displayed by application blobviewer.

-

You need two entries in the configuration files for this to work:

-
    -
  • In $RECOLL_CONFDIR/mimemap (typically ~/.recoll/mimemap), add -the following line:

    -
    .blob = application/x-blobapp
    -
    -
    -

    Note that the MIME type is made up here, and you could call it -diesel/oil just the same.

    -
  • -
  • In $RECOLL_CONFDIR/mimeview under the [view] section, add:

    -
    application/x-blobapp = blobviewer %f
    -
    -
    -

    We are supposing that blobviewer wants a file name parameter here, -you would use %u if it liked URLs better.

    -
  • -
-

If you just wanted to change the application used by RCL to display a -MIME type which it already knows, you would just need to edit -mimeview. The entries you add in your personal file override those -in the central configuration, which you do not need to alter. -mimeview can also be modified from the Gui.

-
-
-
Adding indexing support for a new file type
-

Let us now imagine that the above .blob files actually contain indexable -text and that you know how to extract it with a command line program. -Getting RCL to index the files is easy. You need to perform the above -alteration, and also to add data to the mimeconf file (typically in -~/.recoll/mimeconf):

-
    -
  • Under the [index] section, add the following line (more about the -rclblob indexing script later):

    -
    application/x-blobapp = exec rclblob
    -
    -
    -

    Or if the files are mostly text and you don’t need to process them -for indexing:

    -
    application/x-blobapp = internal text/plain
    -
    -
    -
  • -
  • Under the [icons] section, you should choose an icon to be -displayed for the files inside the result lists. Icons are normally -64x64 pixels PNG files which live in /usr/share/recoll/images.

    -
  • -
  • Under the [categories] section, you should add the MIME type -where it makes sense (you can also create a category). Categories may -be used for filtering in advanced search.

    -
  • -
-

The rclblob handler should be an executable program or script which -exists inside /usr/share/recoll/filters. It will be given a file -name as argument and should output the text or html contents on the -standard output.

-

The filter programming section describes in -more detail how to write an input handler.

-
-
-
-
-
- - -
-
-
- -
-
- - - - - - - \ No newline at end of file diff --git a/src/doc/user/sphinx/conf.py b/src/doc/user/sphinx/conf.py deleted file mode 100644 index 56f10816..00000000 --- a/src/doc/user/sphinx/conf.py +++ /dev/null @@ -1,339 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# -# recoll documentation build configuration file, created by -# sphinx-quickstart on Fri Apr 12 19:48:21 2019. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -# -# needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# -# source_suffix = ['.rst', '.md'] -source_suffix = '.rst' - -# The encoding of source files. -# -# source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'usermanual' - -# General information about the project. -project = 'recoll' -copyright = '2019, J.F. Dockes' -author = 'J.F. Dockes' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '1.25.12' -# The full version, including alpha/beta/rc tags. -release = '1.25.12' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -# -# today = '' -# -# Else, today_fmt is used as the format for a strftime call. -# -# today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This patterns also effect to html_static_path and html_extra_path -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -# -# default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -# -# add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -# -# add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -# -# show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -# modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -# keep_warnings = False - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = False - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = 'alabaster' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# -# html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -# html_theme_path = [] - -# The name for this set of Sphinx documents. -# " v documentation" by default. -# -# html_title = 'recoll v1.25.12' - -# A shorter title for the navigation bar. Default is the same as html_title. -# -# html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -# -# html_logo = None - -# The name of an image file (relative to this directory) to use as a favicon of -# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -# -# html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -# -# html_extra_path = [] - -# If not None, a 'Last updated on:' timestamp is inserted at every page -# bottom, using the given strftime format. -# The empty string is equivalent to '%b %d, %Y'. -# -# html_last_updated_fmt = None - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -# -# html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -# -# html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -# -# html_additional_pages = {} - -# If false, no module index is generated. -# -# html_domain_indices = True - -# If false, no index is generated. -# -# html_use_index = True - -# If true, the index is split into individual pages for each letter. -# -# html_split_index = False - -# If true, links to the reST sources are added to the pages. -# -# html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -# -# html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -# -# html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -# -# html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -# html_file_suffix = None - -# Language to be used for generating the HTML full-text search index. -# Sphinx supports the following languages: -# 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja' -# 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr', 'zh' -# -# html_search_language = 'en' - -# A dictionary with options for the search language support, empty by default. -# 'ja' uses this config value. -# 'zh' user can custom change `jieba` dictionary path. -# -# html_search_options = {'type': 'default'} - -# The name of a javascript file (relative to the configuration directory) that -# implements a search results scorer. If empty, the default will be used. -# -# html_search_scorer = 'scorer.js' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'recolldoc' - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'recoll.tex', 'recoll Documentation', - 'J.F. Dockes', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -# -# latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -# -# latex_use_parts = False - -# If true, show page references after internal links. -# -# latex_show_pagerefs = False - -# If true, show URL addresses after external links. -# -# latex_show_urls = False - -# Documents to append as an appendix to all manuals. -# -# latex_appendices = [] - -# It false, will not define \strong, \code, itleref, \crossref ... but only -# \sphinxstrong, ..., \sphinxtitleref, ... To help avoid clash with user added -# packages. -# -# latex_keep_old_macro_names = True - -# If false, no module index is generated. -# -# latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'recoll', 'recoll Documentation', - [author], 1) -] - -# If true, show URL addresses after external links. -# -# man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'recoll', 'recoll Documentation', - author, 'recoll', 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -# -# texinfo_appendices = [] - -# If false, no module index is generated. -# -# texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -# -# texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -# -# texinfo_no_detailmenu = False diff --git a/src/doc/user/sphinx/usermanual.rst b/src/doc/user/sphinx/index.rst similarity index 99% rename from src/doc/user/sphinx/usermanual.rst rename to src/doc/user/sphinx/index.rst index 8807f3b0..0c520ad4 100644 --- a/src/doc/user/sphinx/usermanual.rst +++ b/src/doc/user/sphinx/index.rst @@ -154,7 +154,7 @@ discriminate two terms based on diacritics (``sake`` / ``saké``, RCL can optionally store the raw terms, without accent stripping or case conversion. In this configuration, default searches will behave as before, but it is possible to perform searches sensitive to case and -diacritics. This is described in more detail in the `section about index +diacritics. This is described in more detail in the section about `index case and diacritics sensitivity <#RCL.INDEXING.CONFIG.SENS>`__. RCL has many parameters which define exactly what to index, and how to @@ -186,7 +186,7 @@ However, there are other ways to perform RCL searches: - A `command line interface <#RCL.SEARCH.COMMANDLINE>`__. -- A `Python programming interface <#RCL.PROGRAM.PYTHONAPI>`__ +- A `Pythonprogramming interface <#RCL.PROGRAM.PYTHONAPI>`__ - A `KDE KIO slave module <#RCL.SEARCH.KIO>`__. @@ -586,7 +586,7 @@ determines what subtrees and files get indexed. The applications needed to index file types other than text, HTML or email (ie: pdf, postscript, ms-word...) are described in the `external -packages section. <#RCL.INSTALL.EXTERNAL>`__ +packages section <#RCL.INSTALL.EXTERNAL>`__. As of Recoll 1.18 there are two incompatible types of Recoll indexes, depending on the treatment of character case and diacritics. A `further @@ -1934,7 +1934,7 @@ list and any entry field (the end of lines will be taken care of). Multiple indexes ~~~~~~~~~~~~~~~~ -See the `section describing the use of multiple +See the section describing `the use of multiple indexes <#RCL.INDEXING.CONFIG.MULTIPLE>`__ for generalities. Only the aspects concerning the ``recoll`` GUI are described here. @@ -2326,7 +2326,7 @@ indexes are searched. - Edit result page HTML header insert: allows you to define text inserted at the end of the result page HTML header. More detail in the `result list customisation - section. <#RCL.SEARCH.GUI.CUSTOM.RESLIST>`__ + section <#RCL.SEARCH.GUI.CUSTOM.RESLIST>`__. - Date format: allows specifying the format used for displaying dates inside the result list. This should be specified as an strftime() @@ -2415,7 +2415,7 @@ two elements: - HTML code inside the header section. For versions 1.21 and later, this is also used for the `snippets - window <#RCL.SEARCH.GUI.RESULTLIST.MENU.SNIPPETS>`__ + window <#RCL.SEARCH.GUI.RESULTLIST.MENU.SNIPPETS>`__. The paragraph format and the header fragment can be edited from the Result list tab of the GUI configuration. @@ -2925,7 +2925,7 @@ RCL currently manages the following default fields: RCL 1.20 and later have a way to specify aliases for the field names, which will save typing, for example by aliasing ``filename`` to fn or ``containerfilename`` to cfn. See the `section about the ``fields`` -file <#RCL.INSTALL.CONFIG.FIELDS>`__ +file <#RCL.INSTALL.CONFIG.FIELDS>`__. The document input handlers used while indexing have the possibility to create other fields with arbitrary names, and aliases may be defined in diff --git a/src/doc/user/usermanual.html b/src/doc/user/usermanual.html index 95bc9522..557f5dd1 100644 --- a/src/doc/user/usermanual.html +++ b/src/doc/user/usermanual.html @@ -663,10 +663,10 @@ alink="#0000FF"> conversion. In this configuration, default searches will behave as before, but it is possible to perform searches sensitive to case and diacritics. This is described in more - detail in the section - about index case and diacritics sensitivity.

+ "2.3.2. Index case and diacritics sensitivity">index + case and diacritics sensitivity.

Recoll has many parameters which define exactly what to index, and how to classify and decode the source documents. These are kept in @@ -720,7 +720,7 @@ alink="#0000FF">

  • A Python programming + "application">Pythonprogramming interface

  • @@ -1359,7 +1359,7 @@ alink="#0000FF"> described in the external packages - section.

    + section.

    As of Recoll 1.18 there are two incompatible types of Recoll indexes, depending on the treatment of character case and diacritics. A - recoll.conf .

    + recoll.conf.

    Creating and updating the index can be done from the command line:

    recollindex -c xapi.
                     (More about wildcards here).

    + "3.8.1. More about wildcards">here ).

    Regular expression
    @@ -3447,13 +3447,12 @@ recoll -c -

    See the See the section describing section describing the use - of multiple indexes for generalities. Only the - aspects concerning the recoll GUI are - described here.

    + "2.3.1. Multiple indexes">the use of multiple + indexes for generalities. Only the aspects concerning + the recoll + GUI are described here.

    A recoll program instance is always associated with a specific index, which is the one to be updated when requested from @@ -4029,7 +4028,7 @@ recoll -c result list customisation - section.

    + section.

  • Date format: @@ -4124,7 +4123,7 @@ recoll -c : a list of words which automatically get turned into ext:xxx file name suffix clauses - when starting a query language query (ie: + when starting a query language query (e.g.: doc xls xlsx...). This will save some typing for people who use file types a lot when querying.

    @@ -4184,7 +4183,7 @@ recoll -c snippets - window

    + window.

  • @@ -4893,7 +4892,7 @@ recoll -c cfn. See the section about the - fields file

    + fields file.

    The document input handlers used while indexing have the possibility to create other fields with arbitrary names, and aliases may be defined in the configuration, so that diff --git a/src/doc/user/usermanual.xml b/src/doc/user/usermanual.xml index 10396899..19a55939 100644 --- a/src/doc/user/usermanual.xml +++ b/src/doc/user/usermanual.xml @@ -90,8 +90,9 @@ directories section). On Unix/Linux, you may need to install the - appropriate supporting - applications for document types that need them (for + appropriate + supporting applications + for document types that need them (for example antiword for Microsoft Word files). @@ -230,14 +231,15 @@ stripping or case conversion. In this configuration, default searches will behave as before, but it is possible to perform searches sensitive to case and diacritics. This is described in more detail in - the section about index case - and diacritics sensitivity. + the section about + index case and diacritics sensitivity. + &RCL; has many parameters which define exactly what to index, and how to classify and decode the source - documents. These are kept in configuration files. A - default configuration is copied into a standard location + documents. These are kept in + configuration files. + A default configuration is copied into a standard location (usually something like /usr/share/recoll/examples) during installation. The default values set by the @@ -253,8 +255,8 @@ the recoll GUI are stored in the standard location defined by Qt. - The indexing - process is started automatically (after asking permission), the + The indexing process + is started automatically (after asking permission), the first time you execute the recoll GUI. Indexing can also be performed by executing the recollindex command. &RCL; indexing is multithreaded by default when appropriate @@ -267,23 +269,22 @@ options to help you find what you are looking for. However, there are other ways to perform &RCL; searches: - A - command line interface. - A - Python - programming interface - A - KDE KIO slave - module. - A Ubuntu Unity Scope + A + command line interface. + + A + Pythonprogramming interface + + A KDE KIO slave module. + + A Ubuntu Unity + Scope module. - A Gnome Shell Search - Provider. - A WEB - interface. + A Gnome Shell + Search Provider. + + A + WEB interface. @@ -333,18 +334,15 @@ - <link linkend="RCL.INDEXING.PERIODIC"> - Periodic (or batch) indexing:</link> + <link linkend="RCL.INDEXING.PERIODIC">Periodic (or batch) indexing:</link> recollindex is executed at discrete times. The typical usage is to have a nightly run - - programmed into + programmed into your cron file. - <link linkend="RCL.INDEXING.MONITOR">Real - time indexing:</link> + <link linkend="RCL.INDEXING.MONITOR">Real time indexing:</link> recollindex runs permanently as a daemon and uses a file system alteration monitor (e.g. inotify) to detect file @@ -364,8 +362,8 @@ With &RCL; 1.24 and newer, it is also possible to set up an index so that only a subset of the tree will be monitored and the rest will be covered by batch/incremental indexing. (See the - details in the Real time - indexing section. + details in the Real time indexing + section. The choice of method and the parameters used can be configured from the recoll GUI: @@ -396,8 +394,8 @@ Configurations, multiple indexes &RCL; supports defining multiple indexes, each defined by its - own configuration - directory, in which several configuration files describe + own configuration directory, + in which several configuration files describe what should be indexed and how. A default personal configuration directory @@ -462,9 +460,9 @@ that some parameters should be consistent among the configurations for indexes which are to be used together. - See the section about configuring multiple - indexes for more detail + See the section about + configuring multiple indexes + for more detail @@ -472,8 +470,8 @@ Document types &RCL; knows about quite a few different document types. The parameters for document types recognition and - processing are set in - configuration files. + processing are set in configuration files. + Most file types, like HTML or word processing files, only hold one document. Some file types, like email folders or zip @@ -490,7 +488,7 @@ Other file types (ie: postscript, pdf, ms-word, rtf ...) need external applications for preprocessing. The list is in the - installation + installation section. After every indexing operation, &RCL; updates a list of commands that would be needed for indexing existing files types. This list can be displayed by selecting the menu option @@ -520,8 +518,8 @@ You can also define an exclusive list of MIME types to be indexed (no others will be indexed), by settting - the - indexedmimetypes configuration variable. Example: + the indexedmimetypes + configuration variable. Example: indexedmimetypes = text/html application/pdf It is possible to redefine this parameter for @@ -536,9 +534,8 @@ excludedmimetypes or indexedmimetypes, can be set either by editing - the configuration - file (recoll.conf) for - the index, or by using the GUI index configuration tool. + the configuration file (recoll.conf) + for the index, or by using the GUI index configuration tool. Note about MIME types When editing the indexedmimetypes @@ -614,9 +611,9 @@ For a given configuration directory, you can specify a non-default storage location for the index by setting the dbdir parameter in the configuration file - (see the configuration - section). This method would mainly be of use if you wanted + (see the + configuration section). + This method would mainly be of use if you wanted to keep the configuration directory in its default location, but desired another location for the index, typically out of disk occupation or performance concerns. @@ -637,9 +634,9 @@ the index in ~/.indexes-email/xapiandb/. - Using multiple configuration directories and configuration - options allows you to tailor multiple configurations and + Using multiple configuration directories and + configuration options + allows you to tailor multiple configurations and indexes to handle whatever subset of the available data you wish to make searchable. @@ -753,8 +750,8 @@ control which areas of the file system are indexed, and how files are processed. These variables can be set either by editing the text files or by using the - dialogs in the - recoll GUI. + dialogs in the recoll GUI. + The first time you start recoll, you will be asked whether or not you would like it to build the @@ -775,19 +772,19 @@ man page, but the most current information will most likely be the comments inside the sample file. The most immediately useful variable is probably - - topdirs, + topdirs, which determines what subtrees and files get indexed. The applications needed to index file types other than text, HTML or email (ie: pdf, postscript, ms-word...) are - described in the external - packages section. + described in the external packages section. + As of Recoll 1.18 there are two incompatible types of Recoll indexes, depending on the treatment of character case and - diacritics. A further - section describes the two types in more detail. + diacritics. A + further section + describes the two types in more detail. Multiple indexes @@ -836,8 +833,8 @@ have the same option concerning character case and diacritics stripping, but there are other constraints. Most of the relevant parameters are described in the - linked - section. + linked section. + The different search interfaces (GUI, command line, ...) have different methods to define the set of indexes to be @@ -921,8 +918,9 @@ recoll -c /path/to/my/new/config between terms, returning different results when searching for US and us or resume and résumé. - Read the section about search - case and diacritics sensitivity for more details. + Read the + section about search case and diacritics sensitivity + for more details. The type of index to be created is controlled by the indexStripChars configuration @@ -1089,8 +1087,9 @@ recoll -c /path/to/my/new/config The meaning for most entries in the interface is self-evident and documented by a ToolTip popup on the text label. For more detail, you will need to - refer to the configuration - section of this guide. + refer to the + configuration section + of this guide. The configuration tool normally respects the comments and most of the formatting inside the configuration file, so @@ -1185,8 +1184,7 @@ recoll -c /path/to/my/new/config By default, other attributes are handled as &RCL; fields. On Linux, the user prefix is removed from the name. This can be configured more precisely inside - the - fields configuration file. + the fields configuration file. @@ -1200,9 +1198,8 @@ recoll -c /path/to/my/new/config indexing. See the - section - about the metadatacmds field in - the main configuration chapter for a description of the + section about the metadatacmds field + in the main configuration chapter for a description of the configuration syntax. As an example, if you would want &RCL; to use tags managed by @@ -1632,8 +1629,8 @@ recoll -c /path/to/my/new/config &RCL; provides a configuration option to specify the minimum time before which a file, specified by a wildcard pattern, cannot be reindexed. See the mondelaypatterns parameter in - the - configuration section. + the configuration section. + @@ -1682,8 +1679,8 @@ recoll -c /path/to/my/new/config Some searches can be quite complex, and you may want to re-use them later, perhaps with some tweaking. &RCL; versions 1.21 and later can save and restore searches, using XML files. See - Saving and restoring - queries. + Saving and restoring queries. + Simple search @@ -1712,8 +1709,9 @@ recoll -c /path/to/my/new/config for documents where at least one of the terms appear. The Query Language features are - described in a separate - section. + described in + a separate section. + All search modes allow terms to be expanded with wildcards characters (*, ?, @@ -1760,8 +1758,7 @@ recoll -c /path/to/my/new/config a search for Floor will only look for floor, in any character case. Stemming can also be disabled globally in the preferences. When using a raw index, - the rules are a bit more - complicated. + the rules are a bit more complicated. &RCL; remembers the last few searches that you performed. You can directly access the search history by clicking the clock button @@ -1786,12 +1783,8 @@ recoll -c /path/to/my/new/config this mode from the Query Language mode, where you have to care about the syntax. - You can use the - - Tools - Advanced search - - dialog for more complex searches. + You can use the ToolsAdvanced search + dialog for more complex searches. @@ -1840,9 +1833,8 @@ recoll -c /path/to/my/new/config the functionality and use the standard desktop tool. You may also change the choice of applications by editing the - - mimeview configuration file if you find - this more convenient. + mimeview + configuration file if you find this more convenient. Each result entry also has a right-click menu with an Open With entry. This lets you choose an @@ -1854,16 +1846,15 @@ recoll -c /path/to/my/new/config &RCL; has no configured way to preview a given file type (which was indexed by name only), or no configured external editor for the file type. This can sometimes be adjusted simply by tweaking - the - mimemap and - - mimeview configuration files (the latter - can be modified with the user preferences dialog). + the mimemap + and mimeview + configuration files (the latter can be modified with the user + preferences dialog). The format of the result list entries is entirely configurable by using the preference dialog to - edit an HTML - fragment. + edit an HTML fragment. + You can click on the Query details link at the top of the results page to see the query actually @@ -2046,8 +2037,9 @@ recoll -c /path/to/my/new/config The commands defined this way can also be used from links - inside the - result paragraph. + inside the + result paragraph. + As an example, it might make sense to write a script which would move the document to the trash and purge it from the &RCL; @@ -2268,8 +2260,8 @@ recoll -c /path/to/my/new/config toolbar. &RCL; keeps a history of searches. See - - Advanced search history. + Advanced search history. + The dialog has two tabs: @@ -2514,8 +2506,8 @@ recoll -c /path/to/my/new/config Multiple indexes - See the section - describing the use of multiple indexes for + See the section describing + the use of multiple indexes for generalities. Only the aspects concerning the recoll GUI are described here. @@ -2645,8 +2637,7 @@ recoll -c /path/to/my/new/config Wildcards Wildcards can be used inside search terms in all forms - of searches. - More about wildcards. + of searches. More about wildcards. @@ -2744,8 +2735,8 @@ recoll -c /path/to/my/new/config Others Using fields - You can use the query - language and field specifications + You can use the query language + and field specifications to only search certain parts of documents. This can be especially helpful with email, for example only searching emails from a specific originator: @@ -3024,16 +3015,18 @@ recoll -c /path/to/my/new/config Edit result list paragraph format string: allows you to change the presentation of each result list - entry. See the - result list customisation section. + entry. See the + result list customisation section. + Edit result page HTML header insert: allows you to define text inserted at the end of the result page HTML header. - More detail in the - result list customisation section. + More detail in the + result list customisation section. + @@ -3153,12 +3146,12 @@ recoll -c /path/to/my/new/config Newer versions of Recoll (from 1.17) normally use WebKit HTML widgets for the result list and the - - snippets window (this may be disabled at build time). - Total customisation is possible with full support for CSS and - Javascript. Conversely, there are limits to what you can do with - the older Qt QTextBrowser, but still, it is possible to decide - what data each result will contain, and how it will be + snippets window + (this may be disabled at build time). + Total customisation is possible with full support for CSS and + Javascript. Conversely, there are limits to what you can do with + the older Qt QTextBrowser, but still, it is possible to decide + what data each result will contain, and how it will be displayed. The result list presentation can be exhaustively customized @@ -3168,8 +3161,8 @@ recoll -c /path/to/my/new/config The paragraph format HTML code inside the header section. For versions 1.21 and later, this is also used for the - - snippets window + snippets window. + The paragraph format and the header fragment can be edited from the Result list tab of the @@ -3202,8 +3195,7 @@ recoll -c /path/to/my/new/config %IIcon image name. This is normally determined from the MIME type. The associations are defined inside the - - mimeconf configuration file. + mimeconf configuration file. If a thumbnail for the file is found at the standard Freedesktop location, this will be displayed instead. @@ -3262,8 +3254,7 @@ recoll -c /path/to/my/new/config R%N|scriptname will run the corresponding script on the result file (if the document is embedded, the script will be started on the top-level parent). - See the section about - defining scripts. + See the section about defining scripts. In addition to the predefined values above, all strings like %(fieldname) will be replaced by the @@ -3271,8 +3262,7 @@ recoll -c /path/to/my/new/config document. Only stored fields can be accessed in this way, the value of indexed but not stored fields is not known at this point in the search process - (see field - configuration). There are currently very few fields + (see field configuration). There are currently very few fields stored by default, apart from the values above (only author and filename), so this feature will need @@ -3317,9 +3307,7 @@ recoll -c /path/to/my/new/config site, with pictures to show how they look. It is also possible to - - define the value of the snippet separator inside the abstract - section. + define the value of the snippet separator inside the abstract section. @@ -3595,8 +3583,8 @@ recoll -c /path/to/my/new/config allowing accesses from the client. The translations are defined in the - - ptrans configuration file, which + ptrans + configuration file, which can be edited by hand or from the GUI external indexes configuration dialog: Preferences @@ -3699,8 +3687,8 @@ recoll -c /path/to/my/new/config Specifying a wild-card on the left of a term can produce a very slow search (or even an incorrect one if the expansion is truncated because of excessive size). Also see - - More about wildcards. + More about wildcards. + To save you some typing, recent &RCL; versions (1.20 and later) interpret a comma-separated list of terms as an AND list inside the @@ -3714,10 +3702,9 @@ recoll -c /path/to/my/new/config Modifiers can be set on a double-quote value, for example to specify a proximity search (unordered). See - the modifier - section. No space must separate the final - double-quote and the modifiers value, e.g. "two - one"po10 + the modifier section. + No space must separate the final double-quote and the modifiers + value, e.g. "two one"po10 &RCL; currently manages the following default fields: @@ -3774,8 +3761,8 @@ recoll -c /path/to/my/new/config filename to fn or containerfilename to cfn. See the - section about the - fields file + section about the fields file. + The document input handlers used while indexing have the possibility to create other fields with arbitrary names, and @@ -3796,9 +3783,9 @@ recoll -c /path/to/my/new/config (release >= 1.15.8). Tilde expansion will be performed as usual (except for a bug in versions 1.19 to 1.19.11p1). Wildcards will be expanded, but - please have a - look at an important limitation of wildcards in - path filters. + please + have a look + at an important limitation of wildcards in path filters. Relative paths also make sense, for example, dir:share/doc would match either @@ -3943,10 +3930,9 @@ recoll -c /path/to/my/new/config possibly open-ended interval. See the section about the - - fields configuration file for the - details of configuring a field for range searches (list them in the - [values] section). + fields configuration file + for the details of configuring a field for range searches (list + them in the [values] section). @@ -4129,8 +4115,8 @@ recoll -c /path/to/my/new/config Using a * at the end of a word can produce more matches than you would think, and strange search results. You can use the - term - explorer tool to check what completions exist for + term explorer + tool to check what completions exist for a given term. You can also see exactly what search was performed by clicking on the link at the top of the result list. In general, for natural language terms, stem @@ -4213,8 +4199,7 @@ recoll -c /path/to/my/new/config The KDE KIO Slave was - described in a previous - section. + described in a previous section. If you use a recent version of Ubuntu Linux, you may @@ -4395,8 +4380,8 @@ recollindex -c "$confdir" If, after the move, the configuration directory needs to be copied out of the dataset (for example because the thumb drive is too slow), you can set the - - curidxconfdir, variable inside the copied configuration to + curidxconfdir, + variable inside the copied configuration to define the location of the moved one. For example if /home/me/mydata is now mounted onto /media/me/somelabel, but the configuration @@ -4523,9 +4508,8 @@ recollindex -c "$confdir" format can return an arbitrary amount of metadata inside HTML meta tags. These will be processed according to the directives found in - the - fields configuration - file. + the fields configuration file. + The handlers that can handle multiple documents per file return a single piece of data to identify each document inside @@ -4563,9 +4547,9 @@ recollindex -c "$confdir" to add metadata or vary the output character encoding (this will be defined in a configuration file). Additionally, some formatting may be easier to preserve when previewing HTML. Actually the deciding factor - is metadata: &RCL; has a way to - extract metadata from the HTML header and use it for field - searches.. + is metadata: &RCL; has a way to + extract metadata from the HTML header and use it for field searches.. + The RECOLL_FILTER_FORPREVIEW environment variable (values yes, no) @@ -4682,8 +4666,8 @@ recollindex -c "$confdir" The association of files to MIME types is mostly based on name suffixes. The types are defined inside the - - mimemap file. Example: + mimemap file. + Example: .doc = application/msword @@ -4693,9 +4677,8 @@ recollindex -c "$confdir" xdg-mime) to determine a MIME type. The second element is the association of MIME types to handlers - in the - mimeconf file. A sample will probably be - better than a long explanation: + in the mimeconf file. + A sample will probably be better than a long explanation: [index] @@ -4798,8 +4781,7 @@ recollindex -c "$confdir" the header as possible document fields candidates. Documents fields can be processed by the indexer in different ways, for searching or displaying inside query results. This is - described in a following - section. + described in a following section. By default, the indexer will process the standard header @@ -4843,8 +4825,7 @@ recollindex -c "$confdir" As written above, the processing of fields is described - in a further - section. + in a further section. Persistent filters can use another, probably simpler, @@ -4913,8 +4894,7 @@ recollindex -c "$confdir" Some fields may also designated as supporting range queries, meaning that the results may be selected for an interval of its - values. See the - configuration section for more details. + values. See the configuration section for more details. The sequence of events for field processing is as follows: @@ -4943,8 +4923,8 @@ recollindex -c "$confdir" At query time, the field can be displayed inside the result list by using the appropriate directive in the definition of the - result list paragraph - format. All fields are displayed on the fields screen of + result list paragraph format. + All fields are displayed on the fields screen of the preview window (which you can reach through the right-click menu). This is independant of the fact that the search which produced the results used the field or not. @@ -4953,9 +4933,8 @@ recollindex -c "$confdir" You can find more information in the - section about the - fields file, or in comments inside the - file. + section about the fields file, + or in comments inside the file. You can also have a look at the example in the FAQs area, @@ -5020,8 +4999,7 @@ recollindex -c "$confdir" There is a good chance that your system repository has packages for the Recoll Python API, sometimes in a package separate from the main one (maybe named something like python-recoll). Else - refer to the Building from - source chapter. + refer to the Building from source chapter. As an introduction, the following small sample will run a query and list the title and url for each of the results. It would @@ -5128,8 +5106,8 @@ recollindex -c "$confdir" Stored and indexed fields The - fields - file inside the &RCL; configuration defines which + fields file + inside the &RCL; configuration defines which document fields are either indexed (searchable), stored (retrievable with search results), or both. Apart from a few standard/internal @@ -6871,8 +6849,9 @@ other = rclcat:other ptrans specifies query-time path translations. These can be useful - in multiple - cases. + in multiple cases. + + The file has a section for any index which needs translations, either the main one or additional query indexes. The sections are named with the &XAP; index @@ -6980,9 +6959,8 @@ application/x-blobapp = internal text/plain will be given a file name as argument and should output the text or html contents on the standard output. - The filter - programming section describes in more detail how - to write an input handler. + The filter programming + section describes in more detail how to write an input handler.