on master help sign in
Merge branch 'master' into bug/oscar-theme
1d86d00Markus Heiser
@@ -8,6 +8,9 @@ PYOBJECTS = searx
8DOC = docs
8DOC = docs
9PY_SETUP_EXTRAS ?= \[test\]
9PY_SETUP_EXTRAS ?= \[test\]
10
10
11+PYDIST=./dist/py
12+PYBUILD=./build/py
13+
11include utils/makefile.include
14include utils/makefile.include
12include utils/makefile.python
15include utils/makefile.python
13include utils/makefile.sphinx
16include utils/makefile.sphinx
@@ -23,6 +26,7 @@ help:
23 @echo ' install - developer install (./local)'
26 @echo ' install - developer install (./local)'
24 @echo ' uninstall - uninstall (./local)'
27 @echo ' uninstall - uninstall (./local)'
25 @echo ' gh-pages - build docs & deploy on gh-pages branch'
28 @echo ' gh-pages - build docs & deploy on gh-pages branch'
29+ @echo ' clean - drop builds and environments'
26 @echo ''
30 @echo ''
27 @$(MAKE) -s -f utils/makefile.include make-help
31 @$(MAKE) -s -f utils/makefile.include make-help
28 @echo ''
32 @echo ''
README.rst+3−3
@@ -23,13 +23,13 @@ Go to the `searx-docker <https://github.com/searx/searx-docker>`__ project.
23
23
24Without Docker
24Without Docker
25------
25------
26−For all the details, follow this `step by step installation <https://asciimoo.github.io/searx/dev/install/installation.html>`__.
26+For all of the details, follow this `step by step installation <https://asciimoo.github.io/searx/dev/install/installation.html>`__.
27
27
28Note: the documentation needs to be updated.
28Note: the documentation needs to be updated.
29
29
30−If you are in hurry
30+If you are in a hurry
31------
31------
32−- clone source:
32+- clone the source:
33 ``git clone https://github.com/asciimoo/searx.git && cd searx``
33 ``git clone https://github.com/asciimoo/searx.git && cd searx``
34- install dependencies: ``./manage.sh update_packages``
34- install dependencies: ``./manage.sh update_packages``
35- edit your
35- edit your
docs/_themes/searx/static/searx.css+101−1
@@ -24,7 +24,107 @@ p.sidebar-title, .sidebar p {
24 margin: 6pt;
24 margin: 6pt;
25}
25}
26
26
27−.sidebar li {
27+.sidebar li,
28+.hlist li {
28 list-style-type: disclosure-closed;
29 list-style-type: disclosure-closed;
29}
30}
30
31
32+
33+/* admonitions
34+*/
35+
36+div.admonition, div.topic {
37+ background-color: #fafafa;
38+ margin: 8px 0px;
39+ padding: 1em;
40+ border-radius: 3pt 0 0 3pt;
41+ border-top: none;
42+ border-right: none;
43+ border-bottom: none;
44+ border-left: 5pt solid #ccc;
45+}
46+
47+p.admonition-title:after {
48+ content: none;
49+}
50+
51+.admonition.hint { border-color: #416dc0b0; }
52+.admonition.note { border-color: #6c856cb0; }
53+.admonition.tip { border-color: #85c5c2b0; }
54+.admonition.attention { border-color: #ecec97b0; }
55+.admonition.caution { border-color: #a6c677b0; }
56+.admonition.danger { border-color: #d46262b0; }
57+.admonition.important { border-color: #dfa3a3b0; }
58+.admonition.error { border-color: red; }
59+.admonition.warning { border-color: darkred; }
60+
61+.admonition.admonition-generic-admonition-title {
62+ border-color: #416dc0b0;
63+}
64+
65+
66+/* admonitions with (rendered) reST markup examples (:class: rst-example)
67+ *
68+ * .. admonition:: title of the example
69+ * :class: rst-example
70+ * ....
71+*/
72+
73+div.rst-example {
74+ background-color: inherit;
75+ margin: 0;
76+ border-top: none;
77+ border-right: 1px solid #ccc;
78+ border-bottom: none;
79+ border-left: none;
80+ border-radius: none;
81+ padding: 0;
82+}
83+
84+div.rst-example > p.admonition-title {
85+ font-family: Sans Serif;
86+ font-style: italic;
87+ font-size: 0.8em;
88+ display: block;
89+ border-bottom: 1px solid #ccc;
90+ padding: 0.5em 1em;
91+ text-align: right;
92+}
93+
94+/* code block in figures
95+ */
96+
97+div.highlight pre {
98+ text-align: left;
99+}
100+
101+/* Table theme
102+*/
103+
104+thead, tfoot {
105+ background-color: #fff;
106+}
107+
108+th:hover, td:hover {
109+ background-color: #ffc;
110+}
111+
112+thead th, tfoot th, tfoot td, tbody th {
113+ background-color: #fffaef;
114+}
115+
116+tbody tr:nth-child(odd) {
117+ background-color: #fff;
118+}
119+
120+tbody tr:nth-child(even) {
121+ background-color: #fafafa;
122+}
123+
124+caption {
125+ font-family: Sans Serif;
126+ padding: 0.5em;
127+ margin: 0.5em 0 0.5em 0;
128+ caption-side: top;
129+ text-align: left;
130+}
docs/admin/arch_public.dotnew file+33
@@ -0,0 +1,33 @@
1+digraph G {
2+
3+ node [style=filled, shape=box, fillcolor="#ffffcc", fontname="Sans"];
4+ edge [fontname="Sans"];
5+
6+ browser [label="Browser", shape=Mdiamond];
7+ rp [label="Reverse Proxy", href="url to configure reverse proxy"];
8+ filtron [label="Filtron", href="https://github.com/asciimoo/filtron"];
9+ morty [label="Morty", href="https://github.com/asciimoo/morty"];
10+ static [label="Static files", href="url to configure static files"];
11+ uwsgi [label="uwsgi", href="url to configure uwsgi"]
12+ searx1 [label="Searx #1"];
13+ searx2 [label="Searx #2"];
14+ searx3 [label="Searx #3"];
15+ searx4 [label="Searx #4"];
16+
17+ browser -> rp [label="HTTPS"]
18+
19+ subgraph cluster_searx {
20+ label = "Searx instance" fontname="Sans";
21+ bgcolor="#fafafa";
22+ { rank=same; static rp };
23+ rp -> morty [label="optional: images and HTML pages proxy"];
24+ rp -> static [label="optional: reverse proxy serves directly static files"];
25+ rp -> filtron [label="HTTP"];
26+ filtron -> uwsgi [label="HTTP"];
27+ uwsgi -> searx1;
28+ uwsgi -> searx2;
29+ uwsgi -> searx3;
30+ uwsgi -> searx4;
31+ }
32+
33+}
docs/admin/architecture.rstnew file+24
@@ -0,0 +1,24 @@
1+.. _architecture:
2+
3+============
4+Architecture
5+============
6+
7+.. sidebar:: Needs work!
8+
9+ This article needs some work / Searx is a collaborative effort. If you have
10+ any contribution, feel welcome to send us your :pull:`PR <../pulls>`, see
11+ :ref:`how to contribute`.
12+
13+Herein you will find some hints and suggestions about typical architectures of
14+searx infrastructures.
15+
16+We start with a contribution from :pull:`@dalf <1776#issuecomment-567917320>`.
17+It shows a *reference* setup for public searx instances.
18+
19+.. _arch public:
20+
21+.. kernel-figure:: arch_public.dot
22+ :alt: arch_public.dot
23+
24+ Reference architecture of a public searx setup.
docs/admin/buildhosts.rstnew file+103
@@ -0,0 +1,103 @@
1+.. _buildhosts:
2+
3+==========
4+Buildhosts
5+==========
6+
7+.. sidebar:: This article needs some work
8+
9+ If you have any contribution send us your :pull:`PR <../pulls>`, see
10+ :ref:`how to contribute`.
11+
12+To get best results from build, its recommend to install additional packages
13+on build hosts.
14+
15+.. _docs build:
16+
17+Build docs
18+==========
19+
20+.. _Graphviz: https://graphviz.gitlab.io
21+.. _ImageMagick: https://www.imagemagick.org
22+.. _XeTeX: https://tug.org/xetex/
23+.. _dvisvgm: https://dvisvgm.de/
24+
25+.. sidebar:: Sphinx build needs
26+
27+ - ImageMagick_
28+ - Graphviz_
29+ - XeTeX_
30+ - dvisvgm_
31+
32+Most of the sphinx requirements are installed from :origin:`setup.py` and the
33+docs can be build from scratch with ``make docs``. For better math and image
34+processing additional packages are needed. The XeTeX_ needed not only for PDF
35+creation, its also needed for :ref:`math` when HTML output is build.
36+
37+To be able to do :ref:`sphinx:math-support` without CDNs, the math are rendered
38+as images (``sphinx.ext.imgmath`` extension). If your docs build (``make
39+docs``) shows warnings like this::
40+
41+ WARNING: dot(1) not found, for better output quality install \
42+ graphviz from http://www.graphviz.org
43+ ..
44+ WARNING: LaTeX command 'latex' cannot be run (needed for math \
45+ display), check the imgmath_latex setting
46+
47+you need to install additional packages on your build host, to get better HTML
48+output.
49+
50+.. _system requirements:
51+
52+.. tabs::
53+
54+ .. group-tab:: Ubuntu / debian
55+
56+ .. code-block:: sh
57+
58+ $ sudo apt install graphviz imagemagick texlive-xetex librsvg2-bin
59+
60+ .. group-tab:: Arch Linux
61+
62+ .. code-block:: sh
63+
64+ $ sudo pacman -S graphviz imagemagick texlive-bin extra/librsvg
65+
66+ .. group-tab:: Fedora / RHEL
67+
68+ .. code-block:: sh
69+
70+ $ sudo dnf install graphviz graphviz-gd texlive-xetex-bin librsvg2-tools
71+
72+
73+For PDF output you also need:
74+
75+.. tabs::
76+
77+ .. group-tab:: Ubuntu / debian
78+
79+ .. code:: sh
80+
81+ $ sudo apt texlive-latex-recommended texlive-extra-utils ttf-dejavu
82+
83+ .. group-tab:: Arch Linux
84+
85+ .. code:: sh
86+
87+ $ sudo pacman -S texlive-core texlive-latexextra ttf-dejavu
88+
89+ .. group-tab:: Fedora / RHEL
90+
91+ .. code:: sh
92+
93+ $ sudo dnf install \
94+ texlive-collection-fontsrecommended texlive-collection-latex \
95+ dejavu-sans-fonts dejavu-serif-fonts dejavu-sans-mono-fonts
96+
97+.. _system requirements END:
98+
99+.. literalinclude:: ../conf.py
100+ :language: python
101+ :start-after: # sphinx.ext.imgmath setup
102+ :end-before: # sphinx.ext.imgmath setup END
103+
docs/admin/engines.rstnew file+68
@@ -0,0 +1,68 @@
1+.. _engines generic:
2+
3+=======
4+engines
5+=======
6+
7+.. sidebar:: Further reading ..
8+
9+ - :ref:`engines generic`
10+ - :ref:`configured engines`
11+ - :ref:`engine settings`
12+ - :ref:`engine file`
13+
14+============= =========== ==================== ============
15+:ref:`engine settings` :ref:`engine file`
16+------------------------- ---------------------------------
17+Name (cfg) Categories
18+------------------------- ---------------------------------
19+Engine .. Paging support **P**
20+------------------------- -------------------- ------------
21+Shortcut **S** Language support **L**
22+Timeout **TO** Time range support **TR**
23+Disabled **D** Offline **O**
24+------------- ----------- -------------------- ------------
25+Suspend end **SE**
26+------------- ----------- ---------------------------------
27+Safe search **SS**
28+============= =========== =================================
29+
30+Configuration defaults (at built time):
31+
32+.. _configured engines:
33+
34+.. jinja:: webapp
35+
36+ .. flat-table:: Engines configured at built time (defaults)
37+ :header-rows: 1
38+ :stub-columns: 2
39+
40+ * - Name (cfg)
41+ - S
42+ - Engine
43+ - TO
44+ - Categories
45+ - P
46+ - L
47+ - SS
48+ - D
49+ - TR
50+ - O
51+ - SE
52+
53+ {% for name, mod in engines.items() %}
54+
55+ * - {{name}}
56+ - !{{mod.shortcut}}
57+ - {{mod.__name__}}
58+ - {{mod.timeout}}
59+ - {{", ".join(mod.categories)}}
60+ - {{(mod.paging and "y") or ""}}
61+ - {{(mod.language_support and "y") or ""}}
62+ - {{(mod.safesearch and "y") or ""}}
63+ - {{(mod.disabled and "y") or ""}}
64+ - {{(mod.time_range_support and "y") or ""}}
65+ - {{(mod.offline and "y") or ""}}
66+ - {{mod.suspend_end_time}}
67+
68+ {% endfor %}
docs/admin/index.rst+4
@@ -7,5 +7,9 @@ Administrator documentation
7
7
8 installation
8 installation
9 api
9 api
10+ architecture
10 filtron
11 filtron
11 morty
12 morty
13+ engines
14+ plugins
15+ buildhosts
docs/admin/installation.rst+15−7
@@ -114,6 +114,9 @@ content:
114 # Module to import
114 # Module to import
115 module = searx.webapp
115 module = searx.webapp
116
116
117+ # Support running the module from a webserver subdirectory.
118+ route-run = fixpathinfo:
119+
117 # Virtualenv and python path
120 # Virtualenv and python path
118 virtualenv = /usr/local/searx/searx-ve/
121 virtualenv = /usr/local/searx/searx-ve/
119 pythonpath = /usr/local/searx/
122 pythonpath = /usr/local/searx/
@@ -151,7 +154,10 @@ content:
151 server {
154 server {
152 listen 80;
155 listen 80;
153 server_name searx.example.com;
156 server_name searx.example.com;
154− root /usr/local/searx;
157+ root /usr/local/searx/searx;
158+
159+ location /static {
160+ }
155
161
156 location / {
162 location / {
157 include uwsgi_params;
163 include uwsgi_params;
@@ -180,14 +186,13 @@ Add this configuration in the server config file
180
186
181.. code:: nginx
187.. code:: nginx
182
188
183− location = /searx { rewrite ^ /searx/; }
189+ location /searx/static {
184− location /searx {
190+ alias /usr/local/searx/searx/static;
185− try_files $uri @searx;
186 }
191 }
192+
187− location @searx {
193+ location /searx {
188 uwsgi_param SCRIPT_NAME /searx;
194 uwsgi_param SCRIPT_NAME /searx;
189 include uwsgi_params;
195 include uwsgi_params;
190− uwsgi_modifier1 30;
191 uwsgi_pass unix:/run/uwsgi/app/searx/socket;
196 uwsgi_pass unix:/run/uwsgi/app/searx/socket;
192 }
197 }
193
198
@@ -197,6 +202,10 @@ in case of single-user or low-traffic instances.)
197
202
198.. code:: nginx
203.. code:: nginx
199
204
205+ location /searx/static {
206+ alias /usr/local/searx/searx/static;
207+ }
208+
200 location /searx {
209 location /searx {
201 proxy_pass http://127.0.0.1:8888;
210 proxy_pass http://127.0.0.1:8888;
202 proxy_set_header Host $host;
211 proxy_set_header Host $host;
@@ -338,4 +347,3 @@ References
338
347
339* How to: `Setup searx in a couple of hours with a free SSL certificate
348* How to: `Setup searx in a couple of hours with a free SSL certificate
340 <https://www.reddit.com/r/privacytoolsIO/comments/366kvn/how_to_setup_your_own_privacy_respecting_search/>`__
349 <https://www.reddit.com/r/privacytoolsIO/comments/366kvn/how_to_setup_your_own_privacy_respecting_search/>`__
341−
docs/admin/plugins.rstnew file+39
@@ -0,0 +1,39 @@
1+.. _plugins generic:
2+
3+===============
4+Plugins builtin
5+===============
6+
7+.. sidebar:: Further reading ..
8+
9+ - :ref:`dev plugin`
10+
11+Configuration defaults (at built time):
12+
13+:DO: Default on
14+
15+.. _configured plugins:
16+
17+.. jinja:: webapp
18+
19+ .. flat-table:: Plugins configured at built time (defaults)
20+ :header-rows: 1
21+ :stub-columns: 1
22+ :widths: 3 1 9
23+
24+ * - Name
25+ - DO
26+ - Description
27+
28+ JS & CSS dependencies
29+
30+ {% for plgin in plugins %}
31+
32+ * - {{plgin.name}}
33+ - {{(plgin.default_on and "y") or ""}}
34+ - {{plgin.description}}
35+
36+ {% for dep in (plgin.js_dependencies + plgin.css_dependencies) %}
37+ | ``{{dep}}`` {% endfor %}
38+
39+ {% endfor %}
docs/conf.py+34−3
@@ -14,11 +14,18 @@ project = u'searx'
14copyright = u'2015-2019, Adam Tauber, Noémi Ványi'
14copyright = u'2015-2019, Adam Tauber, Noémi Ványi'
15author = u'Adam Tauber'
15author = u'Adam Tauber'
16release, version = VERSION_STRING, VERSION_STRING
16release, version = VERSION_STRING, VERSION_STRING
17+highlight_language = 'none'
17
18
18# General --------------------------------------------------------------
19# General --------------------------------------------------------------
19
20
20master_doc = "index"
21master_doc = "index"
21source_suffix = '.rst'
22source_suffix = '.rst'
23+numfig = True
24+
25+from searx import webapp
26+jinja_contexts = {
27+ 'webapp': dict(**webapp.__dict__)
28+}
22
29
23# usage:: lorem :patch:`f373169` ipsum
30# usage:: lorem :patch:`f373169` ipsum
24extlinks = {}
31extlinks = {}
@@ -32,21 +39,40 @@ extlinks['origin'] = (GIT_URL + '/blob/master/%s', 'git://')
32extlinks['patch'] = (GIT_URL + '/commit/%s', '#')
39extlinks['patch'] = (GIT_URL + '/commit/%s', '#')
33extlinks['search'] = (SEARX_URL + '/%s', '#')
40extlinks['search'] = (SEARX_URL + '/%s', '#')
34extlinks['docs'] = (DOCS_URL + '/%s', 'docs: ')
41extlinks['docs'] = (DOCS_URL + '/%s', 'docs: ')
42+extlinks['pypi'] = ('https://pypi.org/project/%s', 'PyPi: ')
43+extlinks['man'] = ('https://manpages.debian.org/jump?q=%s', '')
44+#extlinks['role'] = (
45+# 'https://www.sphinx-doc.org/en/master/usage/restructuredtext/roles.html#role-%s', '')
46+extlinks['duref'] = (
47+ 'http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#%s', '')
48+extlinks['durole'] = (
49+ 'http://docutils.sourceforge.net/docs/ref/rst/roles.html#%s', '')
50+extlinks['dudir'] = (
51+ 'http://docutils.sourceforge.net/docs/ref/rst/directives.html#%s', '')
52+extlinks['ctan'] = (
53+ 'https://ctan.org/pkg/%s', 'CTAN: ')
35
54
36extensions = [
55extensions = [
56+ 'sphinx.ext.imgmath',
37 'sphinx.ext.extlinks',
57 'sphinx.ext.extlinks',
38 'sphinx.ext.viewcode',
58 'sphinx.ext.viewcode',
39 "sphinx.ext.autodoc",
59 "sphinx.ext.autodoc",
40 "sphinx.ext.intersphinx",
60 "sphinx.ext.intersphinx",
41 "pallets_sphinx_themes",
61 "pallets_sphinx_themes",
42 "sphinx_issues", # https://github.com/sloria/sphinx-issues/blob/master/README.rst
62 "sphinx_issues", # https://github.com/sloria/sphinx-issues/blob/master/README.rst
63+ "sphinxcontrib.jinja", # https://github.com/tardyp/sphinx-jinja
64+ 'linuxdoc.rstFlatTable', # Implementation of the 'flat-table' reST-directive.
65+ 'linuxdoc.kfigure', # Sphinx extension which implements scalable image handling.
66+ "sphinx_tabs.tabs", # https://github.com/djungelorm/sphinx-tabs
43]
67]
44
68
45intersphinx_mapping = {
69intersphinx_mapping = {
46 "python": ("https://docs.python.org/3/", None),
70 "python": ("https://docs.python.org/3/", None),
47− # "flask": ("https://flask.palletsprojects.com/", None),
71+ "flask": ("https://flask.palletsprojects.com/", None),
48 # "werkzeug": ("https://werkzeug.palletsprojects.com/", None),
72 # "werkzeug": ("https://werkzeug.palletsprojects.com/", None),
49− # "jinja": ("https://jinja.palletsprojects.com/", None),
73+ "jinja": ("https://jinja.palletsprojects.com/", None),
74+ "linuxdoc" : ("https://return42.github.io/linuxdoc/", None),
75+ "sphinx" : ("https://www.sphinx-doc.org/en/master/", None),
50}
76}
51
77
52issues_github_path = "asciimoo/searx"
78issues_github_path = "asciimoo/searx"
@@ -54,10 +80,15 @@ issues_github_path = "asciimoo/searx"
54# HTML -----------------------------------------------------------------
80# HTML -----------------------------------------------------------------
55
81
56sys.path.append(os.path.abspath('_themes'))
82sys.path.append(os.path.abspath('_themes'))
57−
58html_theme_path = ['_themes']
83html_theme_path = ['_themes']
59html_theme = "searx"
84html_theme = "searx"
60
85
86+# sphinx.ext.imgmath setup
87+html_math_renderer = 'imgmath'
88+imgmath_image_format = 'svg'
89+imgmath_font_size = 14
90+# sphinx.ext.imgmath setup END
91+
61html_theme_options = {"index_sidebar_logo": True}
92html_theme_options = {"index_sidebar_logo": True}
62html_context = {
93html_context = {
63 "project_links": [
94 "project_links": [
docs/dev/contribution_guide.rst+38−5
@@ -1,3 +1,5 @@
1+.. _how to contribute:
2+
1=================
3=================
2How to contribute
4How to contribute
3=================
5=================
@@ -48,7 +50,20 @@ Code
48====
50====
49
51
50.. _PEP8: https://www.python.org/dev/peps/pep-0008/
52.. _PEP8: https://www.python.org/dev/peps/pep-0008/
53+.. _Conventional Commits: https://www.conventionalcommits.org/
54+.. _Git Commit Good Practice: https://wiki.openstack.org/wiki/GitCommitMessages
55+.. _Structural split of changes:
56+ https://wiki.openstack.org/wiki/GitCommitMessages#Structural_split_of_changes
57+.. _gitmoji: https://gitmoji.carloscuesta.me/
58+.. _Semantic PR: https://github.com/zeke/semantic-pull-requests
59+
60+.. sidebar:: Create good commits!
51
61
62+ - `Structural split of changes`_
63+ - `Conventional Commits`_
64+ - `Git Commit Good Practice`_
65+ - some like to use: gitmoji_
66+ - not yet active: `Semantic PR`_
52
67
53In order to submit a patch, please follow the steps below:
68In order to submit a patch, please follow the steps below:
54
69
@@ -57,6 +72,9 @@ In order to submit a patch, please follow the steps below:
57 - PEP8_ standards apply, except the convention of line length
72 - PEP8_ standards apply, except the convention of line length
58 - Maximum line length is 120 characters
73 - Maximum line length is 120 characters
59
74
75+- The cardinal rule for creating good commits is to ensure there is only one
76+ *logical change* per commit / read `Structural split of changes`_
77+
60- Check if your code breaks existing tests. If so, update the tests or fix your
78- Check if your code breaks existing tests. If so, update the tests or fix your
61 code.
79 code.
62
80
@@ -64,6 +82,16 @@ In order to submit a patch, please follow the steps below:
64
82
65- Add yourself to the :origin:`AUTHORS.rst` file.
83- Add yourself to the :origin:`AUTHORS.rst` file.
66
84
85+- Choose meaning full commit messages, read `Conventional Commits`_
86+
87+ .. code::
88+
89+ <type>[optional scope]: <description>
90+
91+ [optional body]
92+
93+ [optional footer(s)]
94+
67- Create a pull request.
95- Create a pull request.
68
96
69For more help on getting started with searx development, see :ref:`devquickstart`.
97For more help on getting started with searx development, see :ref:`devquickstart`.
@@ -79,6 +107,8 @@ Translation currently takes place on :ref:`transifex <translation>`.
79 Please, do not update translation files in the repo.
107 Please, do not update translation files in the repo.
80
108
81
109
110+.. _contrib docs:
111+
82Documentation
112Documentation
83=============
113=============
84
114
@@ -91,7 +121,7 @@ Documentation
91
121
92The documentation is built using Sphinx_. So in order to be able to generate
122The documentation is built using Sphinx_. So in order to be able to generate
93the required files, you have to install it on your system. Much easier, use
123the required files, you have to install it on your system. Much easier, use
94−Makefile our targets.
124+our :ref:`makefile`.
95
125
96Here is an example which makes a complete rebuild:
126Here is an example which makes a complete rebuild:
97
127
@@ -101,6 +131,7 @@ Here is an example which makes a complete rebuild:
101 ...
131 ...
102 The HTML pages are in dist/docs.
132 The HTML pages are in dist/docs.
103
133
134+.. _make docs-live:
104
135
105live build
136live build
106----------
137----------
@@ -110,9 +141,10 @@ live build
110 It is recommended to assert a complete rebuild before deploying (use
141 It is recommended to assert a complete rebuild before deploying (use
111 ``docs-clean``).
142 ``docs-clean``).
112
143
113−Live build is like WYSIWYG, If you want to edit the documentation, its
144+Live build is like WYSIWYG. If you want to edit the documentation, its
114−recommended to use. The Makefile target ``docs-live`` builds the docs, opens URL
145+recommended to use. The Makefile target ``docs-live`` builds the docs, opens
115−in your favorite browser and rebuilds every time a reST file has been changed.
146+URL in your favorite browser and rebuilds every time a reST file has been
147+changed.
116
148
117.. code:: sh
149.. code:: sh
118
150
@@ -123,12 +155,13 @@ in your favorite browser and rebuilds every time a reST file has been changed.
123 ... Start watching changes
155 ... Start watching changes
124
156
125
157
158+.. _deploy on github.io:
126
159
127deploy on github.io
160deploy on github.io
128-------------------
161-------------------
129
162
130To deploy documentation at :docs:`github.io <.>` use Makefile target
163To deploy documentation at :docs:`github.io <.>` use Makefile target
131−``gh-pages``, which will builds the documentation, clones searx into a sub
164+:ref:`make gh-pages`, which will builds the documentation, clones searx into a sub
132folder ``gh-pages``, cleans it, copies the doc build into and runs all the
165folder ``gh-pages``, cleans it, copies the doc build into and runs all the
133needed git add, commit and push:
166needed git add, commit and push:
134
167
docs/dev/csv_table.txtnew file+6
@@ -0,0 +1,6 @@
1+stub col row 1, column, "loremLorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
2+eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
3+voluptua."
4+stub col row 1, "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita
5+kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.", column
6+stub col row 1, column, column
docs/dev/engine_overview.rst+2
@@ -29,6 +29,7 @@ the ones in the engine file.
29It does not matter if an option is stored in the engine file or in the
29It does not matter if an option is stored in the engine file or in the
30settings. However, the standard way is the following:
30settings. However, the standard way is the following:
31
31
32+.. _engine file:
32
33
33engine file
34engine file
34-----------
35-----------
@@ -43,6 +44,7 @@ time_range_support boolean support search time range
43offline boolean engine runs offline
44offline boolean engine runs offline
44======================= =========== ===========================================
45======================= =========== ===========================================
45
46
47+.. _engine settings:
46
48
47settings.yml
49settings.yml
48------------
50------------
docs/dev/hello.dotnew file+3
@@ -0,0 +1,3 @@
1+graph G {
2+ Hello -- World
3+}
docs/dev/index.rst+2
@@ -11,3 +11,5 @@ Developer documentation
11 search_api
11 search_api
12 plugins
12 plugins
13 translation
13 translation
14+ makefile
15+ reST
docs/dev/makefile.rstnew file+221
@@ -0,0 +1,221 @@
1+.. _makefile:
2+
3+================
4+Makefile Targets
5+================
6+
7+.. _gnu-make: https://www.gnu.org/software/make/manual/make.html#Introduction
8+
9+.. sidebar:: build environment
10+
11+ Before looking deeper at the targets, first read about :ref:`makefile setup`
12+ and :ref:`make pyenv`.
13+
14+With the aim to simplify development cycles, started with :pull:`1756` a
15+``Makefile`` based boilerplate was added. If you are not familiar with
16+Makefiles, we recommend to read gnu-make_ introduction.
17+
18+The usage is simple, just type ``make {target-name}`` to *build* a target.
19+Calling the ``help`` target gives a first overview::
20+
21+ $ make help
22+ test - run developer tests
23+ docs - build documentation
24+ docs-live - autobuild HTML documentation while editing
25+ run - run developer instance
26+ install - developer install (./local)
27+ uninstall - uninstall (./local)
28+ gh-pages - build docs & deploy on gh-pages branch
29+ clean - drop builds and environments
30+ ...
31+
32+.. contents:: Contents
33+ :depth: 2
34+ :local:
35+ :backlinks: entry
36+
37+
38+.. _makefile setup:
39+
40+Setup
41+=====
42+
43+.. _git stash: https://git-scm.com/docs/git-stash
44+
45+The main setup is done in the :origin:`Makefile`::
46+
47+ export GIT_URL=https://github.com/asciimoo/searx
48+ export SEARX_URL=https://searx.me
49+ export DOCS_URL=https://asciimoo.github.io/searx
50+
51+.. sidebar:: fork & upstream
52+
53+ Commit changes in your (local) branch, fork or whatever, but do not push them
54+ upstream / `git stash`_ is your friend.
55+
56+:GIT_URL: Changes this, to point to your searx fork.
57+
58+:SEARX_URL: Changes this, to point to your searx instance.
59+
60+:DOCS_URL: If you host your own (branded) documentation, change this URL.
61+
62+.. _make pyenv:
63+
64+Python environment
65+==================
66+
67+.. sidebar:: activate environment
68+
69+ ``source ./local/py3/bin/activate``
70+
71+With Makefile we do no longer need to build up the virualenv manually (as
72+described in the :ref:`devquickstart` guide). Jump into your git working tree
73+and release a ``make pyenv``:
74+
75+.. code:: sh
76+
77+ $ cd ~/searx-clone
78+ $ make pyenv
79+ PYENV usage: source ./local/py3/bin/activate
80+ ...
81+
82+With target ``pyenv`` a development environment (aka virtualenv) was build up in
83+``./local/py3/``. To make a *developer install* of searx (:origin:`setup.py`)
84+into this environment, use make target ``install``:
85+
86+.. code:: sh
87+
88+ $ make install
89+ PYENV usage: source ./local/py3/bin/activate
90+ PYENV using virtualenv from ./local/py3
91+ PYENV install .
92+
93+You have never to think about intermediate targets like ``pyenv`` or
94+``install``, the ``Makefile`` chains them as requisites. Just run your main
95+target.
96+
97+.. sidebar:: drop environment
98+
99+ To get rid of the existing environment before re-build use :ref:`clean target
100+ <make clean>` first.
101+
102+If you think, something goes wrong with your ./local environment or you change
103+the :origin:`setup.py` file (or the requirements listed in
104+:origin:`requirements-dev.txt` and :origin:`requirements.txt`), you have to call
105+:ref:`make clean`.
106+
107+
108+.. _make run:
109+
110+``make run``
111+============
112+
113+To get up a running a developer instance simply call ``make run``. This enables
114+*debug* option in :origin:`searx/settings.yml`, starts a ``./searx/webapp.py``
115+instance, disables *debug* option again and opens the URL in your favorite WEB
116+browser (:man:`xdg-open`):
117+
118+.. code:: sh
119+
120+ $ make run
121+ PYENV usage: source ./local/py3/bin/activate
122+ PYENV install .
123+ ./local/py3/bin/python ./searx/webapp.py
124+ ...
125+ INFO:werkzeug: * Running on http://127.0.0.1:8888/ (Press CTRL+C to quit)
126+ ...
127+
128+.. _make clean:
129+
130+``make clean``
131+==============
132+
133+Drop all intermediate files, all builds, but keep sources untouched. Includes
134+target ``pyclean`` which drops ./local environment. Before calling ``make
135+clean`` stop all processes using :ref:`make pyenv`.
136+
137+.. code:: sh
138+
139+ $ make clean
140+ CLEAN pyclean
141+ CLEAN clean
142+
143+.. _make docs:
144+
145+``make docs docs-live docs-clean``
146+==================================
147+
148+We describe the usage of the ``doc*`` targets in the :ref:`How to contribute /
149+Documentation <contrib docs>` section. If you want to edit the documentation
150+read our :ref:`make docs-live` section. If you are working in your own brand,
151+adjust your :ref:`Makefile setup <makefile setup>`.
152+
153+
154+.. _make gh-pages:
155+
156+``make gh-pages``
157+=================
158+
159+To deploy on github.io first adjust your :ref:`Makefile setup <makefile
160+setup>`. For any further read :ref:`deploy on github.io`.
161+
162+.. _make test:
163+
164+``make test``
165+=============
166+
167+Runs a series of tests: ``test.pep8``, ``test.unit``, ``test.robot`` and does
168+additional :ref:`pylint checks <make pylint>`. You can run tests selective,
169+e.g.:
170+
171+.. code:: sh
172+
173+ $ make test.pep8 test.unit
174+ . ./local/py3/bin/activate; ./manage.sh pep8_check
175+ [!] Running pep8 check
176+ . ./local/py3/bin/activate; ./manage.sh unit_tests
177+ [!] Running unit tests
178+
179+.. _make pylint:
180+
181+``make pylint``
182+===============
183+
184+.. _Pylint: https://www.pylint.org/
185+
186+Before commiting its recommend to do some (more) linting. Pylint_ is known as
187+one of the best source-code, bug and quality checker for the Python programming
188+language. Pylint_ is not yet a quality gate within our searx project (like
189+:ref:`test.pep8 <make test>` it is), but Pylint_ can help to improve code
190+quality anyway. The pylint profile we use at searx project is found in
191+project's root folder :origin:`.pylintrc`.
192+
193+Code quality is a ongoing process. Don't try to fix all messages from Pylint,
194+run Pylint and check if your changed lines are bringing up new messages. If so,
195+fix it. By this, code quality gets incremental better and if there comes the
196+day, the linting is balanced out, we might decide to add Pylint as a quality
197+gate.
198+
199+
200+``make pybuild``
201+================
202+
203+.. _PyPi: https://pypi.org/
204+.. _twine: https://twine.readthedocs.io/en/latest/
205+
206+Build Python packages in ``./dist/py``.
207+
208+.. code:: sh
209+
210+ $ make pybuild
211+ ...
212+ BUILD pybuild
213+ running sdist
214+ running egg_info
215+ ...
216+ $ ls ./dist/py/
217+ searx-0.15.0-py3-none-any.whl searx-0.15.0.tar.gz
218+
219+To upload packages to PyPi_, there is also a ``upload-pypi`` target. It needs
220+twine_ to be installed. Since you are not the owner of :pypi:`searx` you will
221+never need the latter.
docs/dev/plugins.rst+6
@@ -1,7 +1,13 @@
1+.. _dev plugin:
2+
1=======
3=======
2Plugins
4Plugins
3=======
5=======
4
6
7+.. sidebar:: Further reading ..
8+
9+ - :ref:`plugins generic`
10+
5Plugins can extend or replace functionality of various components of searx.
11Plugins can extend or replace functionality of various components of searx.
6
12
7Example plugin
13Example plugin
docs/dev/quickstart.rst+24−2
@@ -4,15 +4,23 @@
4Development Quickstart
4Development Quickstart
5======================
5======================
6
6
7+.. sidebar:: :ref:`makefile`
8+
9+ For additional developer purpose there are :ref:`makefile`.
10+
7This quickstart guide gets your environment set up with searx. Furthermore, it
11This quickstart guide gets your environment set up with searx. Furthermore, it
8gives a short introduction to the ``manage.sh`` script.
12gives a short introduction to the ``manage.sh`` script.
9
13
10How to setup your development environment
14How to setup your development environment
11=========================================
15=========================================
12
16
17+.. sidebar:: :ref:`make pyenv <make pyenv>`
18+
19+ Alternatively use the :ref:`make pyenv`.
20+
13First, clone the source code of searx to the desired folder. In this case the
21First, clone the source code of searx to the desired folder. In this case the
14source is cloned to ``~/myprojects/searx``. Then create and activate the
22source is cloned to ``~/myprojects/searx``. Then create and activate the
15−searx-ve virtualenv and install the required packages using manage.sh.
23+searx-ve virtualenv and install the required packages using ``manage.sh``.
16
24
17.. code:: sh
25.. code:: sh
18
26
@@ -27,6 +35,10 @@ searx-ve virtualenv and install the required packages using manage.sh.
27How to run tests
35How to run tests
28================
36================
29
37
38+.. sidebar:: :ref:`make test.unit <make test>`
39+
40+ Alternatively use the ``test.pep8``, ``test.unit``, ``test.robot`` targets.
41+
30Tests can be run using the ``manage.sh`` script. Following tests and checks are
42Tests can be run using the ``manage.sh`` script. Following tests and checks are
31available:
43available:
32
44
@@ -41,7 +53,8 @@ For example unit tests are run with the command below:
41
53
42 ./manage.sh unit_tests
54 ./manage.sh unit_tests
43
55
44−For further test options, please consult the help of the ``manage.sh`` script.
56+For further test options, please consult the help of the ``manage.sh`` script or
57+read :ref:`make test`.
45
58
46
59
47How to compile styles and javascript
60How to compile styles and javascript
@@ -97,6 +110,11 @@ After installing grunt, the files can be built using the following command:
97Tips for debugging/development
110Tips for debugging/development
98==============================
111==============================
99
112
113+.. sidebar:: :ref:`make run`
114+
115+ Makefile target ``run`` already enables debug option for your developer
116+ session / see :ref:`make run`.
117+
100Turn on debug logging
118Turn on debug logging
101 Whether you are working on a new engine or trying to eliminate a bug, it is
119 Whether you are working on a new engine or trying to eliminate a bug, it is
102 always a good idea to turn on debug logging. When debug logging is enabled a
120 always a good idea to turn on debug logging. When debug logging is enabled a
@@ -104,6 +122,10 @@ Turn on debug logging
104 message. It can be turned on by setting ``debug: False`` to ``debug: True`` in
122 message. It can be turned on by setting ``debug: False`` to ``debug: True`` in
105 :origin:`settings.yml <searx/settings.yml>`.
123 :origin:`settings.yml <searx/settings.yml>`.
106
124
125+.. sidebar:: :ref:`make test`
126+
127+ Alternatively use the :ref:`make test` targets.
128+
107Run ``./manage.sh tests`` before creating a PR.
129Run ``./manage.sh tests`` before creating a PR.
108 Failing build on Travis is common because of PEP8 checks. So a new commit
130 Failing build on Travis is common because of PEP8 checks. So a new commit
109 must be created containing these format fixes. This phase can be skipped if
131 must be created containing these format fixes. This phase can be skipped if
docs/dev/reST.rstnew file+1428
@@ -0,0 +1,1428 @@
1+.. _reST primer:
2+
3+===========
4+reST primer
5+===========
6+
7+.. sidebar:: KISS_ and readability_
8+
9+ Instead of defining more and more roles, we at searx encourage our
10+ contributors to follow principles like KISS_ and readability_.
11+
12+We at searx are using reStructuredText (aka reST_) markup for all kind of
13+documentation, with the builders from the Sphinx_ project a HTML output is
14+generated and deployed at :docs:`github.io <.>`. For build prerequisites read
15+:ref:`docs build`.
16+
17+The source files of Searx's documentation are located at :origin:`docs`. Sphinx
18+assumes source files to be encoded in UTF-8 by defaul. Run :ref:`make docs-live
19+<make docs-live>` to build HTML while editing.
20+
21+.. sidebar:: Further reading
22+
23+ - Sphinx-Primer_
24+ - `Sphinx markup constructs`_
25+ - reST_, docutils_, `docutils FAQ`_
26+ - Sphinx_, `sphinx-doc FAQ`_
27+ - `sphinx config`_, doctree_
28+ - `sphinx cross references`_
29+ - linuxdoc_
30+ - intersphinx_
31+ - sphinx-jinja_
32+ - `Sphinx's autodoc`_
33+ - `Sphinx's Python domain`_, `Sphinx's C domain`_
34+ - SVG_, ImageMagick_
35+ - DOT_, `Graphviz's dot`_, Graphviz_
36+
37+
38+.. contents:: Contents
39+ :depth: 3
40+ :local:
41+ :backlinks: entry
42+
43+Sphinx_ and reST_ have their place in the python ecosystem. Over that reST is
44+used in popular projects, e.g the Linux kernel documentation `[kernel doc]`_.
45+
46+.. _[kernel doc]: https://www.kernel.org/doc/html/latest/doc-guide/sphinx.html
47+
48+.. sidebar:: Content matters
49+
50+ The readability_ of the reST sources has its value, therefore we recommend to
51+ make sparse usage of reST markup / .. content matters!
52+
53+**reST** is a plaintext markup language, its markup is *mostly* intuitive and
54+you will not need to learn much to produce well formed articles with. I use the
55+word *mostly*: like everything in live, reST has its advantages and
56+disadvantages, some markups feel a bit grumpy (especially if you are used to
57+other plaintext markups).
58+
59+Soft skills
60+===========
61+
62+Before going any deeper into the markup let's face on some **soft skills** a
63+trained author brings with, to reach a well feedback from readers:
64+
65+- Documentation is dedicated to an audience and answers questions from the
66+ audience point of view.
67+- Don't detail things which are general knowledge from the audience point of
68+ view.
69+- Limit the subject, use cross links for any further reading.
70+
71+To be more concrete what a *point of view* means. In the (:origin:`docs`)
72+folder we have three sections (and the *blog* folder), each dedicate to a
73+different group of audience.
74+
75+User's POV: :origin:`docs/user`
76+ A typical user knows about search engines and might have heard about
77+ meta crawlers and privacy.
78+
79+Admin's POV: :origin:`docs/admin`
80+ A typical Admin knows about setting up services on a linux system, but he does
81+ not know all the pros and cons of a searx setup.
82+
83+Developer's POV: :origin:`docs/dev`
84+ Depending on the readability_ of code, a typical developer is able to read and
85+ understand source code. Describe what a item aims to do (e.g. a function).
86+ If the chronological order matters, describe it. Name the *out-of-limits
87+ conditions* and all the side effects a external developer will not know.
88+
89+.. _reST inline markup:
90+
91+Basic inline markup
92+===================
93+
94+.. sidebar:: Inline markup
95+
96+ - :ref:`reST roles`
97+ - :ref:`reST smart ref`
98+
99+Basic inline markup is done with asterisks and backquotes. If asterisks or
100+backquotes appear in running text and could be confused with inline markup
101+delimiters, they have to be escaped with a backslash (``\*pointer``).
102+
103+.. table:: basic inline markup
104+ :widths: 4 3 7
105+
106+ ================================================ ==================== ========================
107+ description rendered markup
108+ ================================================ ==================== ========================
109+ one asterisk for emphasis *italics* ``*italics*``
110+ two asterisks for strong emphasis **boldface** ``**boldface**``
111+ backquotes for code samples and literals ``foo()`` ````foo()````
112+ quote asterisks or backquotes \*foo is a pointer ``\*foo is a pointer``
113+ ================================================ ==================== ========================
114+
115+.. _reST basic structure:
116+
117+Basic article structure
118+=======================
119+
120+The basic structure of an article makes use of heading adornments to markup
121+chapter, sections and subsections.
122+
123+.. _reST template:
124+
125+reST template
126+-------------
127+
128+reST template for an simple article:
129+
130+.. code:: reST
131+
132+ .. _doc refname:
133+
134+ ==============
135+ Document title
136+ ==============
137+
138+ Lorem ipsum dolor sit amet, consectetur adipisici elit .. Further read
139+ :ref:`chapter refname`.
140+
141+ .. _chapter refname:
142+
143+ Chapter
144+ =======
145+
146+ Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
147+ aliquid ex ea commodi consequat ...
148+
149+ .. _section refname:
150+
151+ Section
152+ -------
153+
154+ lorem ..
155+
156+ .. _subsection refname:
157+
158+ Subsection
159+ ~~~~~~~~~~
160+
161+ lorem ..
162+
163+
164+Headings
165+--------
166+
167+#. title - with overline for document title:
168+
169+ .. code:: reST
170+
171+ ==============
172+ Document title
173+ ==============
174+
175+
176+#. chapter - with anchor named ``anchor name``:
177+
178+ .. code:: reST
179+
180+ .. _anchor name:
181+
182+ Chapter
183+ =======
184+
185+#. section
186+
187+ .. code:: reST
188+
189+ Section
190+ -------
191+
192+#. subsection
193+
194+ .. code:: reST
195+
196+ Subsection
197+ ~~~~~~~~~~
198+
199+
200+
201+Anchors & Links
202+===============
203+
204+.. _reST anchor:
205+
206+Anchors
207+-------
208+
209+.. _ref role:
210+ https://www.sphinx-doc.org/en/master/usage/restructuredtext/roles.html#role-ref
211+
212+To refer a point in the documentation a anchor is needed. The :ref:`reST
213+template <reST template>` shows an example where a chapter titled *"Chapters"*
214+gets an anchor named ``chapter title``. Another example from *this* document,
215+where the anchor named ``reST anchor``:
216+
217+.. code:: reST
218+
219+ .. _reST anchor:
220+
221+ Anchors
222+ -------
223+
224+ To refer a point in the documentation a anchor is needed ...
225+
226+To refer anchors use the `ref role`_ markup:
227+
228+.. code:: reST
229+
230+ Visit chapter :ref:`reST anchor`. Or set hyperlink text manualy :ref:`foo
231+ bar <reST anchor>`.
232+
233+.. admonition:: ``:ref:`` role
234+ :class: rst-example
235+
236+ Visist chapter :ref:`reST anchor`. Or set hyperlink text manualy :ref:`foo
237+ bar <reST anchor>`.
238+
239+.. _reST ordinary ref:
240+
241+Link ordinary URL
242+-----------------
243+
244+If you need to reference external URLs use *named* hyperlinks to maintain
245+readability of reST sources. Here is a example taken from *this* article:
246+
247+.. code:: reST
248+
249+ .. _Sphinx Field Lists:
250+ https://www.sphinx-doc.org/en/master/usage/restructuredtext/field-lists.html
251+
252+ With the *named* hyperlink `Sphinx Field Lists`_, the raw text is much more
253+ readable.
254+
255+ And this shows the alternative (less readable) hyperlink markup `Sphinx Field
256+ Lists
257+ <https://www.sphinx-doc.org/en/master/usage/restructuredtext/field-lists.html>`__.
258+
259+.. admonition:: Named hyperlink
260+ :class: rst-example
261+
262+ With the *named* hyperlink `Sphinx Field Lists`_, the raw text is much more
263+ readable.
264+
265+ And this shows the alternative (less readable) hyperlink markup `Sphinx Field
266+ Lists
267+ <https://www.sphinx-doc.org/en/master/usage/restructuredtext/field-lists.html>`__.
268+
269+
270+.. _reST smart ref:
271+
272+Smart refs
273+----------
274+
275+With the power of sphinx.ext.extlinks_ and intersphinx_ referencing external
276+content becomes smart.
277+
278+.. table:: smart refs with sphinx.ext.extlinks_ and intersphinx_
279+ :widths: 4 3 7
280+
281+ ========================== ================================== ====================================
282+ refer ... rendered example markup
283+ ========================== ================================== ====================================
284+ :rst:role:`rfc` :rfc:`822` ``:rfc:`822```
285+ :rst:role:`pep` :pep:`8` ``:pep:`8```
286+ sphinx.ext.extlinks_
287+ --------------------------------------------------------------------------------------------------
288+ project's wiki article :wiki:`Searx-instances` ``:wiki:`Searx-instances```
289+ to docs public URL :docs:`dev/reST.html` ``:docs:`dev/reST.html```
290+ files & folders origin :origin:`docs/dev/reST.rst` ``:origin:`docs/dev/reST.rst```
291+ pull request :pull:`1756` ``:pull:`1756```
292+ patch :patch:`af2cae6` ``:patch:`af2cae6```
293+ PyPi package :pypi:`searx` ``:pypi:`searx```
294+ manual page man :man:`bash` ``:man:`bash```
295+ intersphinx_
296+ --------------------------------------------------------------------------------------------------
297+ external anchor :ref:`python:and` ``:ref:`python:and```
298+ external doc anchor :doc:`jinja:templates` ``:doc:`jinja:templates```
299+ python code object :py:obj:`datetime.datetime` ``:py:obj:`datetime.datetime```
300+ flask code object :py:obj:`flask.Flask` ``:py:obj:`flask.Flask```
301+ ========================== ================================== ====================================
302+
303+
304+Intersphinx is configured in :origin:`docs/conf.py`:
305+
306+.. code:: python
307+
308+ intersphinx_mapping = {
309+ "python": ("https://docs.python.org/3/", None),
310+ "flask": ("https://flask.palletsprojects.com/", None),
311+ "jinja": ("https://jinja.palletsprojects.com/", None),
312+ "linuxdoc" : ("https://return42.github.io/linuxdoc/", None),
313+ "sphinx" : ("https://www.sphinx-doc.org/en/master/", None),
314+ }
315+
316+
317+To list all anchors of the inventory (e.g. ``python``) use:
318+
319+.. code:: sh
320+
321+ $ python -m sphinx.ext.intersphinx https://docs.python.org/3/objects.inv
322+
323+Literal blocks
324+==============
325+
326+The simplest form of :duref:`literal-blocks` is a indented block introduced by
327+two colons (``::``). For highlighting use :dudir:`highlight` or :ref:`reST
328+code` directive. To include literals from external files use directive
329+:dudir:`literalinclude`.
330+
331+.. _reST literal:
332+
333+``::``
334+------
335+
336+.. code:: reST
337+
338+ ::
339+
340+ Literal block
341+
342+ Lorem ipsum dolor::
343+
344+ Literal block
345+
346+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
347+ eirmod tempor invidunt ut labore ::
348+
349+ Literal block
350+
351+.. admonition:: Literal block
352+ :class: rst-example
353+
354+ ::
355+
356+ Literal block
357+
358+ Lorem ipsum dolor::
359+
360+ Literal block
361+
362+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
363+ eirmod tempor invidunt ut labore ::
364+
365+ Literal block
366+
367+
368+.. _reST code:
369+
370+``code-block``
371+--------------
372+
373+.. _pygments: https://pygments.org/languages/
374+
375+.. sidebar:: Syntax highlighting
376+
377+ is handled by pygments_.
378+
379+The :rst:dir:`code-block` directive is a variant of the :dudir:`code` directive
380+with additional options. To learn more about code literals visit
381+:ref:`sphinx:code-examples`.
382+
383+.. code-block:: reST
384+
385+ The URL ``/stats`` handle is shown in :ref:`stats-handle`
386+
387+ .. code-block:: Python
388+ :caption: python code block
389+ :name: stats-handle
390+
391+ @app.route('/stats', methods=['GET'])
392+ def stats():
393+ """Render engine statistics page."""
394+ stats = get_engines_stats()
395+ return render(
396+ 'stats.html'
397+ , stats = stats )
398+
399+.. code-block:: reST
400+
401+.. admonition:: Code block
402+ :class: rst-example
403+
404+ The URL ``/stats`` handle is shown in :ref:`stats-handle`
405+
406+ .. code-block:: Python
407+ :caption: python code block
408+ :name: stats-handle
409+
410+ @app.route('/stats', methods=['GET'])
411+ def stats():
412+ """Render engine statistics page."""
413+ stats = get_engines_stats()
414+ return render(
415+ 'stats.html'
416+ , stats = stats )
417+
418+Unicode substitution
419+====================
420+
421+The :dudir:`unicode directive <unicode-character-codes>` converts Unicode
422+character codes (numerical values) to characters. This directive can only be
423+used within a substitution definition.
424+
425+.. code-block:: reST
426+
427+ .. |copy| unicode:: 0xA9 .. copyright sign
428+ .. |(TM)| unicode:: U+2122
429+
430+ Trademark |(TM)| and copyright |copy| glyphs.
431+
432+.. admonition:: Unicode
433+ :class: rst-example
434+
435+ .. |copy| unicode:: 0xA9 .. copyright sign
436+ .. |(TM)| unicode:: U+2122
437+
438+ Trademark |(TM)| and copyright |copy| glyphs.
439+
440+
441+.. _reST roles:
442+
443+Roles
444+=====
445+
446+.. sidebar:: Further reading
447+
448+ - `Sphinx Roles`_
449+ - :doc:`sphinx:usage/restructuredtext/domains`
450+
451+
452+A *custom interpreted text role* (:duref:`ref <roles>`) is an inline piece of
453+explicit markup. It signifies that that the enclosed text should be interpreted
454+in a specific way.
455+
456+The general markup is one of:
457+
458+.. code:: reST
459+
460+ :rolename:`ref-name`
461+ :rolename:`ref text <ref-name>`
462+
463+.. table:: smart refs with sphinx.ext.extlinks_ and intersphinx_
464+ :widths: 4 3 7
465+
466+ ========================== ================================== ====================================
467+ role rendered example markup
468+ ========================== ================================== ====================================
469+ :rst:role:`guilabel` :guilabel:`&Cancel` ``:guilabel:`&Cancel```
470+ :rst:role:`kbd` :kbd:`C-x C-f` ``:kbd:`C-x C-f```
471+ :rst:role:`menuselection` :menuselection:`Open --> File` ``:menuselection:`Open --> File```
472+ :rst:role:`download` :download:`this file <reST.rst>` ``:download:`this file <reST.rst>```
473+ math_ :math:`a^2 + b^2 = c^2` ``:math:`a^2 + b^2 = c^2```
474+ :rst:role:`ref` :ref:`svg image example` ``:ref:`svg image example```
475+ :rst:role:`command` :command:`ls -la` ``:command:`ls -la```
476+ :durole:`emphasis` :emphasis:`italic` ``:emphasis:`italic```
477+ :durole:`strong` :strong:`bold` ``:strong:`bold```
478+ :durole:`literal` :literal:`foo()` ``:literal:`foo()```
479+ :durole:`subscript` H\ :sub:`2`\ O ``H\ :sub:`2`\ O``
480+ :durole:`superscript` E = mc\ :sup:`2` ``E = mc\ :sup:`2```
481+ :durole:`title-reference` :title:`Time` ``:title:`Time```
482+ ========================== ================================== ====================================
483+
484+Figures & Images
485+================
486+
487+.. sidebar:: Image processing
488+
489+ With the directives from :ref:`linuxdoc <linuxdoc:kfigure>` the build process
490+ is flexible. To get best results in the generated output format, install
491+ ImageMagick_ and Graphviz_.
492+
493+Searx's sphinx setup includes: :ref:`linuxdoc:kfigure`. Scaleable here means;
494+scaleable in sense of the build process. Normally in absence of a converter
495+tool, the build process will break. From the authors POV it’s annoying to care
496+about the build process when handling with images, especially since he has no
497+access to the build process. With :ref:`linuxdoc:kfigure` the build process
498+continues and scales output quality in dependence of installed image processors.
499+
500+If you want to add an image, you should use the ``kernel-figure`` (inheritance
501+of :dudir:`figure`) and ``kernel-image`` (inheritance of :dudir:`image`)
502+directives. E.g. to insert a figure with a scaleable image format use SVG
503+(:ref:`svg image example`):
504+
505+.. code:: reST
506+
507+ .. _svg image example:
508+
509+ .. kernel-figure:: svg_image.svg
510+ :alt: SVG image example
511+
512+ Simple SVG image
513+
514+ To refer the figure, a caption block is needed: :ref:`svg image example`.
515+
516+.. _svg image example:
517+
518+.. kernel-figure:: svg_image.svg
519+ :alt: SVG image example
520+
521+ Simple SVG image.
522+
523+To refer the figure, a caption block is needed: :ref:`svg image example`.
524+
525+DOT files (aka Graphviz)
526+------------------------
527+
528+With :ref:`linuxdoc:kernel-figure` reST support for **DOT** formatted files is
529+given.
530+
531+- `Graphviz's dot`_
532+- DOT_
533+- Graphviz_
534+
535+A simple example is shown in :ref:`dot file example`:
536+
537+.. code:: reST
538+
539+ .. _dot file example:
540+
541+ .. kernel-figure:: hello.dot
542+ :alt: hello world
543+
544+ DOT's hello world example
545+
546+.. admonition:: hello.dot
547+ :class: rst-example
548+
549+ .. _dot file example:
550+
551+ .. kernel-figure:: hello.dot
552+ :alt: hello world
553+
554+ DOT's hello world example
555+
556+``kernel-render`` DOT
557+---------------------
558+
559+Embed *render* markups (or languages) like Graphviz's **DOT** is provided by the
560+:ref:`linuxdoc:kernel-render` directive. A simple example of embedded DOT_ is
561+shown in figure :ref:`dot render example`:
562+
563+.. code:: reST
564+
565+ .. _dot render example:
566+
567+ .. kernel-render:: DOT
568+ :alt: digraph
569+ :caption: Embedded DOT (Graphviz) code
570+
571+ digraph foo {
572+ "bar" -> "baz";
573+ }
574+
575+ Attribute ``caption`` is needed, if you want to refer the figure: :ref:`dot
576+ render example`.
577+
578+Please note :ref:`build tools <linuxdoc:kfigure_build_tools>`. If Graphviz_ is
579+installed, you will see an vector image. If not, the raw markup is inserted as
580+*literal-block*.
581+
582+.. admonition:: kernel-render DOT
583+ :class: rst-example
584+
585+ .. _dot render example:
586+
587+ .. kernel-render:: DOT
588+ :alt: digraph
589+ :caption: Embedded DOT (Graphviz) code
590+
591+ digraph foo {
592+ "bar" -> "baz";
593+ }
594+
595+ Attribute ``caption`` is needed, if you want to refer the figure: :ref:`dot
596+ render example`.
597+
598+``kernel-render`` SVG
599+---------------------
600+
601+A simple example of embedded SVG_ is shown in figure :ref:`svg render example`:
602+
603+.. code:: reST
604+
605+ .. _svg render example:
606+
607+ .. kernel-render:: SVG
608+ :caption: Embedded **SVG** markup
609+ :alt: so-nw-arrow
610+..
611+
612+ .. code:: xml
613+
614+ <?xml version="1.0" encoding="UTF-8"?>
615+ <svg xmlns="http://www.w3.org/2000/svg" version="1.1"
616+ baseProfile="full" width="70px" height="40px"
617+ viewBox="0 0 700 400"
618+ >
619+ <line x1="180" y1="370"
620+ x2="500" y2="50"
621+ stroke="black" stroke-width="15px"
622+ />
623+ <polygon points="585 0 525 25 585 50"
624+ transform="rotate(135 525 25)"
625+ />
626+ </svg>
627+
628+.. admonition:: kernel-render SVG
629+ :class: rst-example
630+
631+ .. _svg render example:
632+
633+ .. kernel-render:: SVG
634+ :caption: Embedded **SVG** markup
635+ :alt: so-nw-arrow
636+
637+ <?xml version="1.0" encoding="UTF-8"?>
638+ <svg xmlns="http://www.w3.org/2000/svg" version="1.1"
639+ baseProfile="full" width="70px" height="40px"
640+ viewBox="0 0 700 400"
641+ >
642+ <line x1="180" y1="370"
643+ x2="500" y2="50"
644+ stroke="black" stroke-width="15px"
645+ />
646+ <polygon points="585 0 525 25 585 50"
647+ transform="rotate(135 525 25)"
648+ />
649+ </svg>
650+
651+
652+
653+
654+.. _reST lists:
655+
656+List markups
657+============
658+
659+Bullet list
660+-----------
661+
662+List markup (:duref:`ref <bullet-lists>`) is simple:
663+
664+.. code:: reST
665+
666+ - This is a bulleted list.
667+
668+ 1. Nested lists are possible, but be aware that they must be separated from
669+ the parent list items by blank line
670+ 2. Second item of nested list
671+
672+ - It has two items, the second
673+ item uses two lines.
674+
675+ #. This is a numbered list.
676+ #. It has two items too.
677+
678+.. admonition:: bullet list
679+ :class: rst-example
680+
681+ - This is a bulleted list.
682+
683+ 1. Nested lists are possible, but be aware that they must be separated from
684+ the parent list items by blank line
685+ 2. Second item of nested list
686+
687+ - It has two items, the second
688+ item uses two lines.
689+
690+ #. This is a numbered list.
691+ #. It has two items too.
692+
693+
694+Horizontal list
695+---------------
696+
697+The :rst:dir:`.. hlist:: <hlist>` transforms a bullet list into a more compact
698+list.
699+
700+.. code:: reST
701+
702+ .. hlist::
703+
704+ - first list item
705+ - second list item
706+ - third list item
707+ ...
708+
709+.. admonition:: hlist
710+ :class: rst-example
711+
712+ .. hlist::
713+
714+ - first list item
715+ - second list item
716+ - third list item
717+ - next list item
718+ - next list item xxxx
719+ - next list item yyyy
720+ - next list item zzzz
721+
722+
723+Definition list
724+---------------
725+
726+.. sidebar:: Note ..
727+
728+ - the term cannot have more than one line of text
729+
730+ - there is **no blank line between term and definition block** // this
731+ distinguishes definition lists (:duref:`ref <definition-lists>`) from block
732+ quotes (:duref:`ref <block-quotes>`).
733+
734+Each definition list (:duref:`ref <definition-lists>`) item contains a term,
735+optional classifiers and a definition. A term is a simple one-line word or
736+phrase. Optional classifiers may follow the term on the same line, each after
737+an inline ' : ' (**space, colon, space**). A definition is a block indented
738+relative to the term, and may contain multiple paragraphs and other body
739+elements. There may be no blank line between a term line and a definition block
740+(*this distinguishes definition lists from block quotes*). Blank lines are
741+required before the first and after the last definition list item, but are
742+optional in-between.
743+
744+Definition lists are created as follows:
745+
746+.. code:: reST
747+
748+ term 1 (up to a line of text)
749+ Definition 1.
750+
751+ See the typo : this line is not a term!
752+
753+ And this is not term's definition. **There is a blank line** in between
754+ the line above and this paragraph. That's why this paragraph is taken as
755+ **block quote** (:duref:`ref <block-quotes>`) and not as term's definition!
756+
757+ term 2
758+ Definition 2, paragraph 1.
759+
760+ Definition 2, paragraph 2.
761+
762+ term 3 : classifier
763+ Definition 3.
764+
765+ term 4 : classifier one : classifier two
766+ Definition 4.
767+
768+.. admonition:: definition list
769+ :class: rst-example
770+
771+ term 1 (up to a line of text)
772+ Definition 1.
773+
774+ See the typo : this line is not a term!
775+
776+ And this is not term's definition. **There is a blank line** in between
777+ the line above and this paragraph. That's why this paragraph is taken as
778+ **block quote** (:duref:`ref <block-quotes>`) and not as term's definition!
779+
780+
781+ term 2
782+ Definition 2, paragraph 1.
783+
784+ Definition 2, paragraph 2.
785+
786+ term 3 : classifier
787+ Definition 3.
788+
789+ term 4 : classifier one : classifier two
790+
791+
792+Quoted paragraphs
793+-----------------
794+
795+Quoted paragraphs (:duref:`ref <block-quotes>`) are created by just indenting
796+them more than the surrounding paragraphs. Line blocks (:duref:`ref
797+<line-blocks>`) are a way of preserving line breaks:
798+
799+.. code:: reST
800+
801+ normal paragraph ...
802+ lorem ipsum.
803+
804+ Quoted paragraph ...
805+ lorem ipsum.
806+
807+ | These lines are
808+ | broken exactly like in
809+ | the source file.
810+
811+
812+.. admonition:: Quoted paragraph and line block
813+ :class: rst-example
814+
815+ normal paragraph ...
816+ lorem ipsum.
817+
818+ Quoted paragraph ...
819+ lorem ipsum.
820+
821+ | These lines are
822+ | broken exactly like in
823+ | the source file.
824+
825+
826+.. _reST field list:
827+
828+Field Lists
829+-----------
830+
831+.. _Sphinx Field Lists:
832+ https://www.sphinx-doc.org/en/master/usage/restructuredtext/field-lists.html
833+
834+.. sidebar:: bibliographic fields
835+
836+ First lines fields are bibliographic fields, see `Sphinx Field Lists`_.
837+
838+Field lists are used as part of an extension syntax, such as options for
839+directives, or database-like records meant for further processing. Field lists
840+are mappings from field names to field bodies. They marked up like this:
841+
842+.. code:: reST
843+
844+ :fieldname: Field content
845+ :foo: first paragraph in field foo
846+
847+ second paragraph in field foo
848+
849+ :bar: Field content
850+
851+.. admonition:: Field List
852+ :class: rst-example
853+
854+ :fieldname: Field content
855+ :foo: first paragraph in field foo
856+
857+ second paragraph in field foo
858+
859+ :bar: Field content
860+
861+
862+They are commonly used in Python documentation:
863+
864+.. code:: python
865+
866+ def my_function(my_arg, my_other_arg):
867+ """A function just for me.
868+
869+ :param my_arg: The first of my arguments.
870+ :param my_other_arg: The second of my arguments.
871+
872+ :returns: A message (just for me, of course).
873+ """
874+
875+Further list blocks
876+-------------------
877+
878+- field lists (:duref:`ref <field-lists>`, with caveats noted in
879+ :ref:`reST field list`)
880+- option lists (:duref:`ref <option-lists>`)
881+- quoted literal blocks (:duref:`ref <quoted-literal-blocks>`)
882+- doctest blocks (:duref:`ref <doctest-blocks>`)
883+
884+
885+Admonitions
886+===========
887+
888+Sidebar
889+-------
890+
891+Sidebar is an eye catcher, often used for admonitions pointing further stuff or
892+site effects. Here is the source of the sidebar :ref:`on top of this page <reST
893+primer>`.
894+
895+.. code:: reST
896+
897+ .. sidebar:: KISS_ and readability_
898+
899+ Instead of defining more and more roles, we at searx encourage our
900+ contributors to follow principles like KISS_ and readability_.
901+
902+Generic admonition
903+------------------
904+
905+The generic :dudir:`admonition <admonitions>` needs a title:
906+
907+.. code:: reST
908+
909+ .. admonition:: generic admonition title
910+
911+ lorem ipsum ..
912+
913+
914+.. admonition:: generic admonition title
915+
916+ lorem ipsum ..
917+
918+
919+Specific admonitions
920+--------------------
921+
922+Specific admonitions: :dudir:`hint`, :dudir:`note`, :dudir:`tip` :dudir:`attention`,
923+:dudir:`caution`, :dudir:`danger`, :dudir:`error`, , :dudir:`important`, and
924+:dudir:`warning` .
925+
926+.. code:: reST
927+
928+ .. hint::
929+
930+ lorem ipsum ..
931+
932+ .. note::
933+
934+ lorem ipsum ..
935+
936+ .. warning::
937+
938+ lorem ipsum ..
939+
940+
941+.. hint::
942+
943+ lorem ipsum ..
944+
945+.. note::
946+
947+ lorem ipsum ..
948+
949+.. tip::
950+
951+ lorem ipsum ..
952+
953+.. attention::
954+
955+ lorem ipsum ..
956+
957+.. caution::
958+
959+ lorem ipsum ..
960+
961+.. danger::
962+
963+ lorem ipsum ..
964+
965+.. important::
966+
967+ lorem ipsum ..
968+
969+.. error::
970+
971+ lorem ipsum ..
972+
973+.. warning::
974+
975+ lorem ipsum ..
976+
977+
978+Tables
979+======
980+
981+.. sidebar:: Nested tables
982+
983+ Nested tables are ugly! Not all builder support nested tables, don't use
984+ them!
985+
986+ASCII-art tables like :ref:`reST simple table` and :ref:`reST grid table` might
987+be comfortable for readers of the text-files, but they have huge disadvantages
988+in the creation and modifying. First, they are hard to edit. Think about
989+adding a row or a column to a ASCII-art table or adding a paragraph in a cell,
990+it is a nightmare on big tables.
991+
992+
993+.. sidebar:: List tables
994+
995+ For meaningful patch and diff use :ref:`reST flat table`.
996+
997+Second the diff of modifying ASCII-art tables is not meaningful, e.g. widening a
998+cell generates a diff in which also changes are included, which are only
999+ascribable to the ASCII-art. Anyway, if you prefer ASCII-art for any reason,
1000+here are some helpers:
1001+
1002+* `Emacs Table Mode`_
1003+* `Online Tables Generator`_
1004+
1005+.. _reST simple table:
1006+
1007+Simple tables
1008+-------------
1009+
1010+:duref:`Simple tables <simple-tables>` allow *colspan* but not *rowspan*. If
1011+your table need some metadata (e.g. a title) you need to add the ``.. table::
1012+directive`` :dudir:`(ref) <table>` in front and place the table in its body:
1013+
1014+.. code:: reST
1015+
1016+ .. table:: foo gate truth table
1017+ :widths: grid
1018+ :align: left
1019+
1020+ ====== ====== ======
1021+ Inputs Output
1022+ ------------- ------
1023+ A B A or B
1024+ ====== ====== ======
1025+ False
1026+ --------------------
1027+ True
1028+ --------------------
1029+ True False True
1030+ (foo)
1031+ ------ ------ ------
1032+ False True
1033+ (foo)
1034+ ====== =============
1035+
1036+.. admonition:: Simple ASCII table
1037+ :class: rst-example
1038+
1039+ .. table:: foo gate truth table
1040+ :widths: grid
1041+ :align: left
1042+
1043+ ====== ====== ======
1044+ Inputs Output
1045+ ------------- ------
1046+ A B A or B
1047+ ====== ====== ======
1048+ False
1049+ --------------------
1050+ True
1051+ --------------------
1052+ True False True
1053+ (foo)
1054+ ------ ------ ------
1055+ False True
1056+ (foo)
1057+ ====== =============
1058+
1059+
1060+
1061+.. _reST grid table:
1062+
1063+Grid tables
1064+-----------
1065+
1066+:duref:`Grid tables <grid-tables>` allow colspan *colspan* and *rowspan*:
1067+
1068+.. code:: reST
1069+
1070+ .. table:: grid table example
1071+ :widths: 1 1 5
1072+
1073+ +------------+------------+-----------+
1074+ | Header 1 | Header 2 | Header 3 |
1075+ +============+============+===========+
1076+ | body row 1 | column 2 | column 3 |
1077+ +------------+------------+-----------+
1078+ | body row 2 | Cells may span columns.|
1079+ +------------+------------+-----------+
1080+ | body row 3 | Cells may | - Cells |
1081+ +------------+ span rows. | - contain |
1082+ | body row 4 | | - blocks. |
1083+ +------------+------------+-----------+
1084+
1085+.. admonition:: ASCII grid table
1086+ :class: rst-example
1087+
1088+ .. table:: grid table example
1089+ :widths: 1 1 5
1090+
1091+ +------------+------------+-----------+
1092+ | Header 1 | Header 2 | Header 3 |
1093+ +============+============+===========+
1094+ | body row 1 | column 2 | column 3 |
1095+ +------------+------------+-----------+
1096+ | body row 2 | Cells may span columns.|
1097+ +------------+------------+-----------+
1098+ | body row 3 | Cells may | - Cells |
1099+ +------------+ span rows. | - contain |
1100+ | body row 4 | | - blocks. |
1101+ +------------+------------+-----------+
1102+
1103+
1104+.. _reST flat table:
1105+
1106+flat-table
1107+----------
1108+
1109+The ``flat-table`` is a further developed variant of the :ref:`list tables
1110+<linuxdoc:list-table-directives>`. It is a double-stage list similar to the
1111+:dudir:`list-table` with some additional features:
1112+
1113+column-span: ``cspan``
1114+ with the role ``cspan`` a cell can be extended through additional columns
1115+
1116+row-span: ``rspan``
1117+ with the role ``rspan`` a cell can be extended through additional rows
1118+
1119+auto-span:
1120+ spans rightmost cell of a table row over the missing cells on the right side
1121+ of that table-row. With Option ``:fill-cells:`` this behavior can changed
1122+ from *auto span* to *auto fill*, which automatically inserts (empty) cells
1123+ instead of spanning the last cell.
1124+
1125+options:
1126+ :header-rows: [int] count of header rows
1127+ :stub-columns: [int] count of stub columns
1128+ :widths: [[int] [int] ... ] widths of columns
1129+ :fill-cells: instead of auto-span missing cells, insert missing cells
1130+
1131+roles:
1132+ :cspan: [int] additional columns (*morecols*)
1133+ :rspan: [int] additional rows (*morerows*)
1134+
1135+The example below shows how to use this markup. The first level of the staged
1136+list is the *table-row*. In the *table-row* there is only one markup allowed,
1137+the list of the cells in this *table-row*. Exception are *comments* ( ``..`` )
1138+and *targets* (e.g. a ref to :ref:`row 2 of table's body <row body 2>`).
1139+
1140+.. code:: reST
1141+
1142+ .. flat-table:: ``flat-table`` example
1143+ :header-rows: 2
1144+ :stub-columns: 1
1145+ :widths: 1 1 1 1 2
1146+
1147+ * - :rspan:`1` head / stub
1148+ - :cspan:`3` head 1.1-4
1149+
1150+ * - head 2.1
1151+ - head 2.2
1152+ - head 2.3
1153+ - head 2.4
1154+
1155+ * .. row body 1 / this is a comment
1156+
1157+ - row 1
1158+ - :rspan:`2` cell 1-3.1
1159+ - cell 1.2
1160+ - cell 1.3
1161+ - cell 1.4
1162+
1163+ * .. Comments and targets are allowed on *table-row* stage.
1164+ .. _`row body 2`:
1165+
1166+ - row 2
1167+ - cell 2.2
1168+ - :rspan:`1` :cspan:`1`
1169+ cell 2.3 with a span over
1170+
1171+ * col 3-4 &
1172+ * row 2-3
1173+
1174+ * - row 3
1175+ - cell 3.2
1176+
1177+ * - row 4
1178+ - cell 4.1
1179+ - cell 4.2
1180+ - cell 4.3
1181+ - cell 4.4
1182+
1183+ * - row 5
1184+ - cell 5.1 with automatic span to rigth end
1185+
1186+ * - row 6
1187+ - cell 6.1
1188+ - ..
1189+
1190+
1191+.. admonition:: List table
1192+ :class: rst-example
1193+
1194+ .. flat-table:: ``flat-table`` example
1195+ :header-rows: 2
1196+ :stub-columns: 1
1197+ :widths: 1 1 1 1 2
1198+
1199+ * - :rspan:`1` head / stub
1200+ - :cspan:`3` head 1.1-4
1201+
1202+ * - head 2.1
1203+ - head 2.2
1204+ - head 2.3
1205+ - head 2.4
1206+
1207+ * .. row body 1 / this is a comment
1208+
1209+ - row 1
1210+ - :rspan:`2` cell 1-3.1
1211+ - cell 1.2
1212+ - cell 1.3
1213+ - cell 1.4
1214+
1215+ * .. Comments and targets are allowed on *table-row* stage.
1216+ .. _`row body 2`:
1217+
1218+ - row 2
1219+ - cell 2.2
1220+ - :rspan:`1` :cspan:`1`
1221+ cell 2.3 with a span over
1222+
1223+ * col 3-4 &
1224+ * row 2-3
1225+
1226+ * - row 3
1227+ - cell 3.2
1228+
1229+ * - row 4
1230+ - cell 4.1
1231+ - cell 4.2
1232+ - cell 4.3
1233+ - cell 4.4
1234+
1235+ * - row 5
1236+ - cell 5.1 with automatic span to rigth end
1237+
1238+ * - row 6
1239+ - cell 6.1
1240+ - ..
1241+
1242+
1243+CSV table
1244+---------
1245+
1246+CSV table might be the choice if you want to include CSV-data from a outstanding
1247+(build) process into your documentation.
1248+
1249+.. code:: reST
1250+
1251+ .. csv-table:: CSV table example
1252+ :header: .. , Column 1, Column 2
1253+ :widths: 2 5 5
1254+ :stub-columns: 1
1255+ :file: csv_table.txt
1256+
1257+Content of file ``csv_table.txt``:
1258+
1259+.. literalinclude:: csv_table.txt
1260+
1261+.. admonition:: CSV table
1262+ :class: rst-example
1263+
1264+ .. csv-table:: CSV table example
1265+ :header: .. , Column 1, Column 2
1266+ :widths: 3 5 5
1267+ :stub-columns: 1
1268+ :file: csv_table.txt
1269+
1270+Templating
1271+==========
1272+
1273+.. sidebar:: Build environment
1274+
1275+ All *generic-doc* tasks are running in the :ref:`build environment <make
1276+ pyenv>`.
1277+
1278+Templating is suitable for documentation which is created generic at the build
1279+time. The sphinx-jinja_ extension evaluates jinja_ templates in the :ref:`build
1280+environment <make pyenv>` (with searx modules installed). We use this e.g. to
1281+build chapter: :ref:`engines generic`. Below the jinja directive from the
1282+:origin:`docs/admin/engines.rst` is shown:
1283+
1284+.. literalinclude:: ../admin/engines.rst
1285+ :language: reST
1286+ :start-after: .. _configured engines:
1287+
1288+The context for the template is selected in the line ``.. jinja:: webapp``. In
1289+sphinx's build configuration (:origin:`docs/conf.py`) the ``webapp`` context
1290+points to the name space of the python module: ``webapp``.
1291+
1292+.. code:: py
1293+
1294+ from searx import webapp
1295+ jinja_contexts = {
1296+ 'webapp': dict(**webapp.__dict__)
1297+ }
1298+
1299+
1300+Tabbed views
1301+============
1302+
1303+.. _sphinx-tabs: https://github.com/djungelorm/sphinx-tabs
1304+.. _basic-tabs: https://github.com/djungelorm/sphinx-tabs#basic-tabs
1305+.. _group-tabs: https://github.com/djungelorm/sphinx-tabs#group-tabs
1306+.. _code-tabs: https://github.com/djungelorm/sphinx-tabs#code-tabs
1307+
1308+With `sphinx-tabs`_ extension we have *tabbed views*. To provide installation
1309+instructions with one tab per distribution we use the `group-tabs`_ directive,
1310+others are basic-tabs_ and code-tabs_. Below a *group-tab* example from
1311+:ref:`docs build` is shown:
1312+
1313+.. literalinclude:: ../admin/buildhosts.rst
1314+ :language: reST
1315+ :start-after: .. _system requirements:
1316+ :end-before: .. _system requirements END:
1317+
1318+
1319+.. _math:
1320+
1321+Math equations
1322+==============
1323+
1324+.. _Mathematics: https://en.wikibooks.org/wiki/LaTeX/Mathematics
1325+.. _amsmath user guide:
1326+ http://vesta.informatik.rwth-aachen.de/ftp/pub/mirror/ctan/macros/latex/required/amsmath/amsldoc.pdf
1327+
1328+.. sidebar:: About LaTeX
1329+
1330+ - `amsmath user guide`_
1331+ - Mathematics_
1332+ - :ref:`docs build`
1333+
1334+The input language for mathematics is LaTeX markup using the :ctan:`amsmath`
1335+package.
1336+
1337+To embed LaTeX markup in reST documents, use role :rst:role:`:math: <math>` for
1338+inline and directive :rst:dir:`.. math:: <math>` for block markup.
1339+
1340+.. code:: reST
1341+
1342+ In :math:numref:`schroedinger general` the time-dependent Schrödinger equation
1343+ is shown.
1344+
1345+ .. math::
1346+ :label: schroedinger general
1347+
1348+ \mathrm{i}\hbar\dfrac{\partial}{\partial t} |\,\psi (t) \rangle =
1349+ \hat{H} |\,\psi (t) \rangle.
1350+
1351+.. admonition:: LaTeX math equation
1352+ :class: rst-example
1353+
1354+ In :math:numref:`schroedinger general` the time-dependent Schrödinger equation
1355+ is shown.
1356+
1357+ .. math::
1358+ :label: schroedinger general
1359+
1360+ \mathrm{i}\hbar\dfrac{\partial}{\partial t} |\,\psi (t) \rangle =
1361+ \hat{H} |\,\psi (t) \rangle.
1362+
1363+
1364+The next example shows the difference of ``\tfrac`` (*textstyle*) and ``\dfrac``
1365+(*displaystyle*) used in a inline markup or another fraction.
1366+
1367+.. code:: reST
1368+
1369+ ``\tfrac`` **inline example** :math:`\tfrac{\tfrac{1}{x}+\tfrac{1}{y}}{y-z}`
1370+ ``\dfrac`` **inline example** :math:`\dfrac{\dfrac{1}{x}+\dfrac{1}{y}}{y-z}`
1371+
1372+.. admonition:: Line spacing
1373+ :class: rst-example
1374+
1375+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
1376+ eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
1377+ voluptua. ...
1378+ ``\tfrac`` **inline example** :math:`\tfrac{\tfrac{1}{x}+\tfrac{1}{y}}{y-z}`
1379+ At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd
1380+ gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
1381+
1382+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
1383+ eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
1384+ voluptua. ...
1385+ ``\tfrac`` **inline example** :math:`\dfrac{\dfrac{1}{x}+\dfrac{1}{y}}{y-z}`
1386+ At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd
1387+ gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
1388+
1389+
1390+.. _KISS: https://en.wikipedia.org/wiki/KISS_principle
1391+
1392+.. _readability: https://docs.python-guide.org/writing/style/
1393+.. _Sphinx-Primer:
1394+ http://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html
1395+.. _reST: https://docutils.sourceforge.io/rst.html
1396+.. _Sphinx Roles:
1397+ https://www.sphinx-doc.org/en/master/usage/restructuredtext/roles.html
1398+.. _Sphinx: http://www.sphinx-doc.org
1399+.. _`sphinx-doc FAQ`: http://www.sphinx-doc.org/en/stable/faq.html
1400+.. _Sphinx markup constructs:
1401+ http://www.sphinx-doc.org/en/stable/markup/index.html
1402+.. _`sphinx cross references`:
1403+ http://www.sphinx-doc.org/en/stable/markup/inline.html#cross-referencing-arbitrary-locations
1404+.. _sphinx.ext.extlinks:
1405+ https://www.sphinx-doc.org/en/master/usage/extensions/extlinks.html
1406+.. _intersphinx: http://www.sphinx-doc.org/en/stable/ext/intersphinx.html
1407+.. _sphinx config: http://www.sphinx-doc.org/en/stable/config.html
1408+.. _Sphinx's autodoc: http://www.sphinx-doc.org/en/stable/ext/autodoc.html
1409+.. _Sphinx's Python domain:
1410+ http://www.sphinx-doc.org/en/stable/domains.html#the-python-domain
1411+.. _Sphinx's C domain:
1412+ http://www.sphinx-doc.org/en/stable/domains.html#cross-referencing-c-constructs
1413+.. _doctree:
1414+ http://www.sphinx-doc.org/en/master/extdev/tutorial.html?highlight=doctree#build-phases
1415+.. _docutils: http://docutils.sourceforge.net/docs/index.html
1416+.. _docutils FAQ: http://docutils.sourceforge.net/FAQ.html
1417+.. _linuxdoc: https://return42.github.io/linuxdoc
1418+.. _jinja: https://jinja.palletsprojects.com/
1419+.. _sphinx-jinja: https://github.com/tardyp/sphinx-jinja
1420+.. _SVG: https://www.w3.org/TR/SVG11/expanded-toc.html
1421+.. _DOT: https://graphviz.gitlab.io/_pages/doc/info/lang.html
1422+.. _`Graphviz's dot`: https://graphviz.gitlab.io/_pages/pdf/dotguide.pdf
1423+.. _Graphviz: https://graphviz.gitlab.io
1424+.. _ImageMagick: https://www.imagemagick.org
1425+
1426+.. _`Emacs Table Mode`: https://www.emacswiki.org/emacs/TableMode
1427+.. _`Online Tables Generator`: http://www.tablesgenerator.com/text_tables
1428+.. _`OASIS XML Exchange Table Model`: https://www.oasis-open.org/specs/tm9901.html
docs/dev/search_api.rst+7
@@ -14,6 +14,13 @@ Furthermore, two enpoints ``/`` and ``/search`` are available for querying.
14Parameters
14Parameters
15==========
15==========
16
16
17+.. sidebar:: Further reading ..
18+
19+ - :ref:`engines generic`
20+ - :ref:`configured engines`
21+ - :ref:`engine settings`
22+ - :ref:`engine file`
23+
17``q`` : required
24``q`` : required
18 The search query. This string is passed to external search services. Thus,
25 The search query. This string is passed to external search services. Thus,
19 searx supports syntax of each search service. For example, ``site:github.com
26 searx supports syntax of each search service. For example, ``site:github.com
docs/dev/svg_image.svgnew file+10
@@ -0,0 +1,10 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<!-- originate: https://commons.wikimedia.org/wiki/File:Variable_Resistor.svg -->
3+<svg xmlns="http://www.w3.org/2000/svg"
4+ version="1.1" baseProfile="full"
5+ width="70px" height="40px" viewBox="0 0 700 400">
6+ <line x1="0" y1="200" x2="700" y2="200" stroke="black" stroke-width="20px"/>
7+ <rect x="100" y="100" width="500" height="200" fill="white" stroke="black" stroke-width="20px"/>
8+ <line x1="180" y1="370" x2="500" y2="50" stroke="black" stroke-width="15px"/>
9+ <polygon points="585 0 525 25 585 50" transform="rotate(135 525 25)"/>
10+</svg>
requirements-dev.txt+3
@@ -11,3 +11,6 @@ transifex-client==0.12.2
11unittest2==1.1.0
11unittest2==1.1.0
12zope.testrunner==4.5.1
12zope.testrunner==4.5.1
13selenium==3.141.0
13selenium==3.141.0
14+linuxdoc @ git+http://github.com/return42/linuxdoc.git
15+sphinx-jinja
16+sphinx-tabs
searx/engines/bing.py+2−3
@@ -89,8 +89,7 @@ def response(resp):
89 'content': content})
89 'content': content})
90
90
91 try:
91 try:
92− result_len_container = "".join(eval_xpath(dom, '//span[@class="sb_count"]/text()'))
92+ result_len_container = "".join(eval_xpath(dom, '//span[@class="sb_count"]//text()'))
93− result_len_container = utils.to_string(result_len_container)
94 if "-" in result_len_container:
93 if "-" in result_len_container:
95 # Remove the part "from-to" for paginated request ...
94 # Remove the part "from-to" for paginated request ...
96 result_len_container = result_len_container[result_len_container.find("-") * 2 + 2:]
95 result_len_container = result_len_container[result_len_container.find("-") * 2 + 2:]
@@ -102,7 +101,7 @@ def response(resp):
102 logger.debug('result error :\n%s', e)
101 logger.debug('result error :\n%s', e)
103 pass
102 pass
104
103
105− if _get_offset_from_pageno(resp.search_params.get("pageno", 0)) > result_len:
104+ if result_len and _get_offset_from_pageno(resp.search_params.get("pageno", 0)) > result_len:
106 return []
105 return []
107
106
108 results.append({'number_of_results': result_len})
107 results.append({'number_of_results': result_len})
searx/engines/flickr_noapi.py+17−9
@@ -109,14 +109,22 @@ def response(resp):
109 else:
109 else:
110 url = build_flickr_url(photo['ownerNsid'], photo['id'])
110 url = build_flickr_url(photo['ownerNsid'], photo['id'])
111
111
112+ result = {
112− results.append({'url': url,
113+ 'url': url,
113− 'title': title,
114− 'img_src': img_src,
114+ 'img_src': img_src,
115− 'thumbnail_src': thumbnail_src,
115+ 'thumbnail_src': thumbnail_src,
116− 'content': content,
117− 'author': author,
118− 'source': source,
116+ 'source': source,
119− 'img_format': img_format,
117+ 'img_format': img_format,
120− 'template': 'images.html'})
118+ 'template': 'images.html'
119+ }
120+ try:
121+ result['author'] = author.encode('utf-8')
122+ result['title'] = title.encode('utf-8')
123+ result['content'] = content.encode('utf-8')
124+ except:
125+ result['author'] = ''
126+ result['title'] = ''
127+ result['content'] = ''
128+ results.append(result)
121
129
122 return results
130 return results
searx/engines/ina.py+6−3
@@ -32,7 +32,7 @@ base_url = 'https://www.ina.fr'
32search_url = base_url + '/layout/set/ajax/recherche/result?autopromote=&hf={ps}&b={start}&type=Video&r=&{query}'
32search_url = base_url + '/layout/set/ajax/recherche/result?autopromote=&hf={ps}&b={start}&type=Video&r=&{query}'
33
33
34# specific xpath variables
34# specific xpath variables
35−results_xpath = '//div[contains(@class,"search-results--list")]/div[@class="media"]'
35+results_xpath = '//div[contains(@class,"search-results--list")]//div[@class="media-body"]'
36url_xpath = './/a/@href'
36url_xpath = './/a/@href'
37title_xpath = './/h3[@class="h3--title media-heading"]'
37title_xpath = './/h3[@class="h3--title media-heading"]'
38thumbnail_xpath = './/img/@src'
38thumbnail_xpath = './/img/@src'
@@ -65,8 +65,11 @@ def response(resp):
65 videoid = result.xpath(url_xpath)[0]
65 videoid = result.xpath(url_xpath)[0]
66 url = base_url + videoid
66 url = base_url + videoid
67 title = p.unescape(extract_text(result.xpath(title_xpath)))
67 title = p.unescape(extract_text(result.xpath(title_xpath)))
68+ try:
68− thumbnail = extract_text(result.xpath(thumbnail_xpath)[0])
69+ thumbnail = extract_text(result.xpath(thumbnail_xpath)[0])
70+ except:
71+ thumbnail = ''
69− if thumbnail[0] == '/':
72+ if thumbnail and thumbnail[0] == '/':
70 thumbnail = base_url + thumbnail
73 thumbnail = base_url + thumbnail
71 d = extract_text(result.xpath(publishedDate_xpath)[0])
74 d = extract_text(result.xpath(publishedDate_xpath)[0])
72 d = d.split('/')
75 d = d.split('/')
searx/engines/microsoft_academic.py+2
@@ -45,6 +45,8 @@ def request(query, params):
45def response(resp):
45def response(resp):
46 results = []
46 results = []
47 response_data = loads(resp.text)
47 response_data = loads(resp.text)
48+ if not response_data:
49+ return results
48
50
49 for result in response_data['results']:
51 for result in response_data['results']:
50 url = _get_url(result)
52 url = _get_url(result)
searx/engines/scanr_structures.py+1−1
@@ -29,7 +29,7 @@ def request(query, params):
29 params['url'] = search_url
29 params['url'] = search_url
30 params['method'] = 'POST'
30 params['method'] = 'POST'
31 params['headers']['Content-type'] = "application/json"
31 params['headers']['Content-type'] = "application/json"
32− params['data'] = dumps({"query": query,
32+ params['data'] = dumps({"query": query.decode('utf-8'),
33 "searchField": "ALL",
33 "searchField": "ALL",
34 "sortDirection": "ASC",
34 "sortDirection": "ASC",
35 "sortOrder": "RELEVANCY",
35 "sortOrder": "RELEVANCY",
searx/engines/spotify.py+14
@@ -12,10 +12,14 @@
12
12
13from json import loads
13from json import loads
14from searx.url_utils import urlencode
14from searx.url_utils import urlencode
15+import requests
16+import base64
15
17
16# engine dependent config
18# engine dependent config
17categories = ['music']
19categories = ['music']
18paging = True
20paging = True
21+api_client_id = None
22+api_client_secret = None
19
23
20# search-url
24# search-url
21url = 'https://api.spotify.com/'
25url = 'https://api.spotify.com/'
@@ -31,6 +35,16 @@ def request(query, params):
31
35
32 params['url'] = search_url.format(query=urlencode({'q': query}), offset=offset)
36 params['url'] = search_url.format(query=urlencode({'q': query}), offset=offset)
33
37
38+ r = requests.post(
39+ 'https://accounts.spotify.com/api/token',
40+ data={'grant_type': 'client_credentials'},
41+ headers={'Authorization': 'Basic ' + base64.b64encode(
42+ "{}:{}".format(api_client_id, api_client_secret).encode('utf-8')
43+ ).decode('utf-8')}
44+ )
45+ j = loads(r.text)
46+ params['headers'] = {'Authorization': 'Bearer {}'.format(j.get('access_token'))}
47+
34 return params
48 return params
35
49
36
50
searx/settings.yml+20−15
@@ -79,9 +79,10 @@ engines:
79 categories : science
79 categories : science
80 timeout : 4.0
80 timeout : 4.0
81
81
82+# tmp suspended: dh key too small
82− - name : base
83+# - name : base
83− engine : base
84+# engine : base
84− shortcut : bs
85+# shortcut : bs
85
86
86 - name : wikipedia
87 - name : wikipedia
87 engine : wikipedia
88 engine : wikipedia
@@ -408,7 +409,7 @@ engines:
408
409
409 - name : library genesis
410 - name : library genesis
410 engine : xpath
411 engine : xpath
411− search_url : http://libgen.io/search.php?req={query}
412+ search_url : https://libgen.is/search.php?req={query}
412 url_xpath : //a[contains(@href,"bookfi.net")]/@href
413 url_xpath : //a[contains(@href,"bookfi.net")]/@href
413 title_xpath : //a[contains(@href,"book/")]/text()[1]
414 title_xpath : //a[contains(@href,"book/")]/text()[1]
414 content_xpath : //td/a[1][contains(@href,"=author")]/text()
415 content_xpath : //td/a[1][contains(@href,"=author")]/text()
@@ -464,7 +465,7 @@ engines:
464 - name : openairedatasets
465 - name : openairedatasets
465 engine : json_engine
466 engine : json_engine
466 paging : True
467 paging : True
467− search_url : http://api.openaire.eu/search/datasets?format=json&page={pageno}&size=10&title={query}
468+ search_url : https://api.openaire.eu/search/datasets?format=json&page={pageno}&size=10&title={query}
468 results_query : response/results/result
469 results_query : response/results/result
469 url_query : metadata/oaf:entity/oaf:result/children/instance/webresource/url/$
470 url_query : metadata/oaf:entity/oaf:result/children/instance/webresource/url/$
470 title_query : metadata/oaf:entity/oaf:result/title/$
471 title_query : metadata/oaf:entity/oaf:result/title/$
@@ -476,7 +477,7 @@ engines:
476 - name : openairepublications
477 - name : openairepublications
477 engine : json_engine
478 engine : json_engine
478 paging : True
479 paging : True
479− search_url : http://api.openaire.eu/search/publications?format=json&page={pageno}&size=10&title={query}
480+ search_url : https://api.openaire.eu/search/publications?format=json&page={pageno}&size=10&title={query}
480 results_query : response/results/result
481 results_query : response/results/result
481 url_query : metadata/oaf:entity/oaf:result/children/instance/webresource/url/$
482 url_query : metadata/oaf:entity/oaf:result/children/instance/webresource/url/$
482 title_query : metadata/oaf:entity/oaf:result/title/$
483 title_query : metadata/oaf:entity/oaf:result/title/$
@@ -552,10 +553,11 @@ engines:
552 timeout : 10.0
553 timeout : 10.0
553 disabled : True
554 disabled : True
554
555
556+# tmp suspended: bad certificate
555− - name : scanr structures
557+# - name : scanr structures
556− shortcut: scs
558+# shortcut: scs
557− engine : scanr_structures
559+# engine : scanr_structures
558− disabled : True
560+# disabled : True
559
561
560 - name : soundcloud
562 - name : soundcloud
561 engine : soundcloud
563 engine : soundcloud
@@ -598,9 +600,12 @@ engines:
598 shortcut : se
600 shortcut : se
599 categories : science
601 categories : science
600
602
603+# Spotify needs API credentials
601− - name : spotify
604+# - name : spotify
602− engine : spotify
605+# engine : spotify
603− shortcut : stf
606+# shortcut : stf
607+# api_client_id : *******
608+# api_client_secret : *******
604
609
605 - name : startpage
610 - name : startpage
606 engine : startpage
611 engine : startpage
@@ -812,7 +817,7 @@ locales:
812doi_resolvers :
817doi_resolvers :
813 oadoi.org : 'https://oadoi.org/'
818 oadoi.org : 'https://oadoi.org/'
814 doi.org : 'https://doi.org/'
819 doi.org : 'https://doi.org/'
815− doai.io : 'http://doai.io/'
820+ doai.io : 'https://doai.io/'
816− sci-hub.tw : 'http://sci-hub.tw/'
821+ sci-hub.tw : 'https://sci-hub.tw/'
817
822
818default_doi_resolver : 'oadoi.org'
823default_doi_resolver : 'oadoi.org'
searx/settings_robot.yml+2−2
@@ -43,7 +43,7 @@ locales:
43doi_resolvers :
43doi_resolvers :
44 oadoi.org : 'https://oadoi.org/'
44 oadoi.org : 'https://oadoi.org/'
45 doi.org : 'https://doi.org/'
45 doi.org : 'https://doi.org/'
46− doai.io : 'http://doai.io/'
46+ doai.io : 'https://doai.io/'
47− sci-hub.tw : 'http://sci-hub.tw/'
47+ sci-hub.tw : 'https://sci-hub.tw/'
48
48
49default_doi_resolver : 'oadoi.org'
49default_doi_resolver : 'oadoi.org'
searx/static/plugins/js/vim_hotkeys.js+10−2
@@ -125,6 +125,14 @@ $(document).ready(function() {
125 }
125 }
126 });
126 });
127
127
128+ function nextResult(current, direction) {
129+ var next = current[direction]();
130+ while (!next.is('.result') && next.length !== 0) {
131+ next = next[direction]();
132+ }
133+ return next
134+ }
135+
128 function highlightResult(which) {
136 function highlightResult(which) {
129 return function() {
137 return function() {
130 var current = $('.result[data-vim-selected]');
138 var current = $('.result[data-vim-selected]');
@@ -157,13 +165,13 @@ $(document).ready(function() {
157 }
165 }
158 break;
166 break;
159 case 'down':
167 case 'down':
160− next = current.next('.result');
168+ next = nextResult(current, 'next');
161 if (next.length === 0) {
169 if (next.length === 0) {
162 next = $('.result:first');
170 next = $('.result:first');
163 }
171 }
164 break;
172 break;
165 case 'up':
173 case 'up':
166− next = current.prev('.result');
174+ next = nextResult(current, 'prev');
167 if (next.length === 0) {
175 if (next.length === 0) {
168 next = $('.result:last');
176 next = $('.result:last');
169 }
177 }
utils/makefile.sphinx+1
@@ -198,6 +198,7 @@ $(GH_PAGES)::
198 $(MAKE) docs
198 $(MAKE) docs
199 [ -d "gh-pages/.git" ] || git clone $(GIT_URL) gh-pages
199 [ -d "gh-pages/.git" ] || git clone $(GIT_URL) gh-pages
200 -cd $(GH_PAGES); git checkout gh-pages >/dev/null
200 -cd $(GH_PAGES); git checkout gh-pages >/dev/null
201+ -cd $(GH_PAGES); git pull
201 -cd $(GH_PAGES); ls -A | grep -v '.git$$' | xargs rm -rf
202 -cd $(GH_PAGES); ls -A | grep -v '.git$$' | xargs rm -rf
202 cp -r $(DOCS_DIST)/* $(GH_PAGES)/
203 cp -r $(DOCS_DIST)/* $(GH_PAGES)/
203 touch $(GH_PAGES)/.nojekyll
204 touch $(GH_PAGES)/.nojekyll