We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Update/refresh installation guide and quick start
Many parts are out of date or confusing. 


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `bokeh/sphinxext/bokeh_plot.py`
Content:
```
1 """ Include Bokeh plots in Sphinx HTML documentation.
2 
3 For other output types, the placeholder text ``[graph]`` will
4 be generated.
5 
6 Usage
7 -----
8 
9 The ``bokeh-plot`` directive can be used by either supplying:
10 
11 1. **A path to a source file** as the argument to the directive::
12 
13     .. bokeh-plot:: path/to/plot.py
14 
15 
16 2. **Inline code** as the content of the directive::
17 
18     .. bokeh-plot::
19 
20         from bokeh.plotting import figure, output_file, show
21 
22         output_file("example.html")
23 
24         x = [1, 2, 3, 4, 5]
25         y = [6, 7, 6, 4, 5]
26 
27         p = figure(title="example", plot_width=300, plot_height=300)
28         p.line(x, y, line_width=2)
29         p.circle(x, y, size=10, fill_color="white")
30 
31         show(p)
32 
33 This directive also works in conjunction with Sphinx autodoc, when
34 used in docstrings.
35 
36 Options
37 -------
38 
39 The ``bokeh-plot`` directive accepts the following options:
40 
41 source-position : enum('above', 'below', 'none')
42     Where to locate the the block of formatted source
43     code (if anywhere).
44 
45 linenos : bool
46     Whether to display line numbers along with the source.
47 
48 emphasize-lines : list[int]
49     A list of source code lines to emphasize.
50 
51 Examples
52 --------
53 
54 The inline example code above produces the following output:
55 
56 ----
57 
58 .. bokeh-plot::
59 
60     from bokeh.plotting import figure, output_file, show
61 
62     output_file("example.html")
63 
64     x = [1, 2, 3, 4, 5]
65     y = [6, 7, 6, 4, 5]
66 
67     p = figure(title="example", plot_width=300, plot_height=300)
68     p.line(x, y, line_width=2)
69     p.circle(x, y, size=10, fill_color="white")
70 
71     show(p)
72 
73 """
74 from __future__ import absolute_import
75 
76 import hashlib
77 from os import makedirs
78 from os.path import basename, dirname, exists, isdir, join, relpath
79 import re
80 from shutil import copy
81 import sys
82 from tempfile import mkdtemp
83 import webbrowser
84 
85 from docutils import nodes
86 from docutils.parsers.rst.directives import choice, flag, unchanged
87 from docutils.statemachine import ViewList
88 
89 import jinja2
90 
91 from sphinx.locale import _
92 from sphinx.util.compat import Directive
93 
94 from .utils import out_of_date
95 from .. import plotting
96 from ..document import Document
97 from ..embed import autoload_static
98 from ..resources import CDN
99 from ..utils import decode_utf8
100 
101 
102 SOURCE_TEMPLATE = jinja2.Template(u"""
103 .. code-block:: python
104    {% if linenos %}:linenos:{% endif %}
105    {% if emphasize_lines %}:emphasize-lines: {{ emphasize_lines }}{% endif %}
106 
107    {{ source|indent(3) }}
108 
109 """)
110 
111 
112 SCRIPT_TEMPLATE = jinja2.Template(u"""
113 <table>
114   <tr>
115     <td>
116     {{ script|indent(4) }}
117     </td>
118   </tr>
119 </table>
120 """)
121 
122 
123 class bokeh_plot(nodes.General, nodes.Element):
124     pass
125 
126 
127 def _source_position(argument):
128     return choice(argument, ('below', 'above', 'none'))
129 
130 
131 class BokehPlotDirective(Directive):
132 
133     has_content = True
134     optional_arguments = 2
135 
136     option_spec = {
137         'source-position' : _source_position,
138         'linenos'         : flag,
139         'emphasize-lines' : unchanged,
140     }
141 
142     def run(self):
143         # filename *or* python code content, but not both
144         if self.arguments and self.content:
145             raise RuntimeError("bokeh-plot:: directive can't have both args and content")
146 
147         env = self.state.document.settings.env
148         app = env.app
149 
150         if not hasattr(env, 'bokeh_plot_tmpdir'):
151             env.bokeh_plot_tmpdir = mkdtemp()
152             app.verbose("creating new temp dir for bokeh-plot cache: %s" % env.bokeh_plot_tmpdir)
153         else:
154             tmpdir = env.bokeh_plot_tmpdir
155             if not exists(tmpdir) or not isdir(tmpdir):
156                 app.verbose("creating new temp dir for bokeh-plot cache: %s" % env.bokeh_plot_tmpdir)
157                 env.bokeh_plot_tmpdir = mkdtemp()
158             else:
159                 app.verbose("using existing temp dir for bokeh-plot cache: %s" % env.bokeh_plot_tmpdir)
160 
161         # TODO (bev) verify that this is always the correct thing
162         rst_source = self.state_machine.node.document['source']
163         rst_dir = dirname(rst_source)
164         rst_filename = basename(rst_source)
165 
166         target_id = "%s.bokeh-plot-%d" % (rst_filename, env.new_serialno('bokeh-plot'))
167         target_node = nodes.target('', '', ids=[target_id])
168         result = [target_node]
169 
170         try:
171             source = self._get_source()
172         except Exception:
173             node = nodes.error(None,
174                                nodes.paragraph(text="Unable to generate Bokeh plot at %s:%d:" % (basename(rst_source), self.lineno)),
175                                nodes.paragraph(text=str(sys.exc_info()[1])))
176             return [node]
177 
178         source_position = self.options.get('source-position', 'below')
179 
180         if source_position == 'above':
181             result += self._get_source_nodes(source)
182 
183         node = bokeh_plot()
184         node['target_id'] = target_id
185         node['source'] = source
186         node['relpath'] = relpath(rst_dir, env.srcdir)
187         node['rst_source'] = rst_source
188         node['rst_lineno'] = self.lineno
189         if 'alt' in self.options:
190             node['alt'] = self.options['alt']
191         if self.arguments:
192             node['path'] = self.arguments[0]
193             env.note_dependency(node['path'])
194         if len(self.arguments) == 2:
195             node['symbol'] = self.arguments[1]
196         result += [node]
197 
198         if source_position == 'below':
199             result += self._get_source_nodes(source)
200 
201         return result
202 
203     def _get_source(self):
204         if self.arguments:
205             source = open(self.arguments[0], "r").read()
206             source = decode_utf8(source)
207         else:
208             source = u""
209             for line in self.content:
210                 source += "%s\n" % line
211         return source
212 
213     def _get_source_nodes(self, source):
214         linenos = 'linenos' in self.options
215         emphasize_lines = self.options.get('emphasize-lines', False)
216         if emphasize_lines: linenos = True
217         result = ViewList()
218         text = SOURCE_TEMPLATE.render(source=source, linenos=linenos, emphasize_lines=emphasize_lines)
219         for line in text.split("\n"):
220             result.append(line, "<bokeh-plot>")
221         node = nodes.paragraph()
222         node.document = self.state.document
223         self.state.nested_parse(result, 0, node)
224         return node.children
225 
226 # patch open and show and save to be no-ops
227 def _noop(*args, **kwargs):
228     pass
229 
230 def _show(obj=None):
231     if obj:
232         plotting._obj = obj
233 
234 webbrowser.open = _noop
235 plotting.save = _noop
236 plotting.show = _show
237 
238 def _render_plot(source, symbol):
239     plotting._default_document = Document()
240     namespace = {}
241     # need to remove any encoding comment before compiling unicode
242     pat = re.compile(r"^# -\*- coding: (.*) -\*-$", re.M)
243     source = pat.sub("", source)
244     code = compile(source, "<string>", mode="exec")
245     eval(code, namespace)
246     # TODO (bev) remove this crap
247     if symbol is not None:
248         if 'bokeh.charts' in source:
249             obj = namespace[symbol].chart.plot
250         else:
251             obj = namespace[symbol]
252     else:
253         obj = plotting._obj
254     return obj
255 
256 def html_visit_bokeh_plot(self, node):
257     env = self.builder.env
258     dest_dir = join(self.builder.outdir, node["relpath"])
259 
260     try:
261         if node.has_key('path'):
262             path = node['path']
263             filename = "bokeh-plot-%s.js" %  hashlib.md5(path.encode('utf-8')).hexdigest()
264             dest_path = join(dest_dir, filename)
265             tmpdir = join(env.bokeh_plot_tmpdir, node["relpath"])
266             if not exists(tmpdir): makedirs(tmpdir)
267             cached_path = join(tmpdir, filename)
268 
269             if out_of_date(path, cached_path) or not exists(cached_path+".script"):
270                 self.builder.app.verbose("generating new plot for '%s'" % path)
271                 plot = _render_plot(node['source'], node.get('symbol'))
272                 js, script = autoload_static(plot, CDN, filename)
273                 with open(cached_path, "w") as f:
274                     f.write(js)
275                 with open(cached_path+".script", "w") as f:
276                     f.write(script)
277             else:
278                 self.builder.app.verbose("using cached plot for '%s'" % path)
279                 script = open(cached_path+".script", "r").read()
280 
281             if not exists(dest_dir): makedirs(dest_dir)
282             copy(cached_path, dest_path)
283         else:
284             filename = node['target_id'] + ".js"
285             dest_path = join(dest_dir, filename)
286             plot = _render_plot(node['source'], None)
287             js, script = autoload_static(plot, CDN, filename)
288             self.builder.app.verbose("saving inline plot at: %s" % dest_path)
289             with open(dest_path, "w") as f:
290                 f.write(js)
291 
292         html = SCRIPT_TEMPLATE.render(script=script)
293         self.body.append(html)
294     except Exception:
295         err_node = nodes.error(None,
296                                nodes.paragraph(text="Unable to generate Bokeh plot at %s:%d:" % (node['rst_source'], node['rst_lineno'])),
297                                nodes.paragraph(text=str(sys.exc_info()[1])))
298         node.children.append(err_node)
299         raise nodes.SkipDeparture
300     else:
301         raise nodes.SkipNode
302 
303 
304 def latex_visit_bokeh_plot(self, node):
305     if 'alt' in node.attributes:
306         self.body.append(_('[graph: %s]') % node['alt'])
307     else:
308         self.body.append(_('[graph]'))
309     raise nodes.SkipNode
310 
311 
312 def texinfo_visit_bokeh_plot(self, node):
313     if 'alt' in node.attributes:
314         self.body.append(_('[graph: %s]') % node['alt'])
315     else:
316         self.body.append(_('[graph]'))
317     raise nodes.SkipNode
318 
319 
320 def text_visit_bokeh_plot(self, node):
321     if 'alt' in node.attributes:
322         self.add_text(_('[graph: %s]') % node['alt'])
323     else:
324         self.add_text(_('[graph]'))
325     raise nodes.SkipNode
326 
327 
328 def man_visit_bokeh_plot(self, node):
329     if 'alt' in node.attributes:
330         self.body.append(_('[graph: %s]') % node['alt'])
331     else:
332         self.body.append(_('[graph]'))
333     raise nodes.SkipNode
334 
335 
336 def setup(app):
337     app.add_node(bokeh_plot,
338                  html=(html_visit_bokeh_plot, None),
339                  latex=(latex_visit_bokeh_plot, None),
340                  texinfo=(texinfo_visit_bokeh_plot, None),
341                  text=(text_visit_bokeh_plot, None),
342                  man=(man_visit_bokeh_plot, None))
343     app.add_directive('bokeh-plot', BokehPlotDirective)
344 
345 
346 
347 
348 
349 
350
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/bokeh/sphinxext/bokeh_plot.py b/bokeh/sphinxext/bokeh_plot.py
--- a/bokeh/sphinxext/bokeh_plot.py
+++ b/bokeh/sphinxext/bokeh_plot.py
@@ -92,7 +92,7 @@
 from sphinx.util.compat import Directive
 
 from .utils import out_of_date
-from .. import plotting
+from .. import charts, io, plotting
 from ..document import Document
 from ..embed import autoload_static
 from ..resources import CDN
@@ -232,6 +232,10 @@
         plotting._obj = obj
 
 webbrowser.open = _noop
+charts.save = _noop
+charts.show = _show
+io.save = _noop
+io.show = _show
 plotting.save = _noop
 plotting.show = _show

{"golden_diff": "diff --git a/bokeh/sphinxext/bokeh_plot.py b/bokeh/sphinxext/bokeh_plot.py\n--- a/bokeh/sphinxext/bokeh_plot.py\n+++ b/bokeh/sphinxext/bokeh_plot.py\n@@ -92,7 +92,7 @@\n from sphinx.util.compat import Directive\n \n from .utils import out_of_date\n-from .. import plotting\n+from .. import charts, io, plotting\n from ..document import Document\n from ..embed import autoload_static\n from ..resources import CDN\n@@ -232,6 +232,10 @@\n         plotting._obj = obj\n \n webbrowser.open = _noop\n+charts.save = _noop\n+charts.show = _show\n+io.save = _noop\n+io.show = _show\n plotting.save = _noop\n plotting.show = _show\n", "issue": "Update/refresh installation guide and quick start\nMany parts are out of date or confusing. \n\n", "before_files": [{"content": "\"\"\" Include Bokeh plots in Sphinx HTML documentation.\n\nFor other output types, the placeholder text ``[graph]`` will\nbe generated.\n\nUsage\n-----\n\nThe ``bokeh-plot`` directive can be used by either supplying:\n\n1. **A path to a source file** as the argument to the directive::\n\n    .. bokeh-plot:: path/to/plot.py\n\n\n2. **Inline code** as the content of the directive::\n\n    .. bokeh-plot::\n\n        from bokeh.plotting import figure, output_file, show\n\n        output_file(\"example.html\")\n\n        x = [1, 2, 3, 4, 5]\n        y = [6, 7, 6, 4, 5]\n\n        p = figure(title=\"example\", plot_width=300, plot_height=300)\n        p.line(x, y, line_width=2)\n        p.circle(x, y, size=10, fill_color=\"white\")\n\n        show(p)\n\nThis directive also works in conjunction with Sphinx autodoc, when\nused in docstrings.\n\nOptions\n-------\n\nThe ``bokeh-plot`` directive accepts the following options:\n\nsource-position : enum('above', 'below', 'none')\n    Where to locate the the block of formatted source\n    code (if anywhere).\n\nlinenos : bool\n    Whether to display line numbers along with the source.\n\nemphasize-lines : list[int]\n    A list of source code lines to emphasize.\n\nExamples\n--------\n\nThe inline example code above produces the following output:\n\n----\n\n.. bokeh-plot::\n\n    from bokeh.plotting import figure, output_file, show\n\n    output_file(\"example.html\")\n\n    x = [1, 2, 3, 4, 5]\n    y = [6, 7, 6, 4, 5]\n\n    p = figure(title=\"example\", plot_width=300, plot_height=300)\n    p.line(x, y, line_width=2)\n    p.circle(x, y, size=10, fill_color=\"white\")\n\n    show(p)\n\n\"\"\"\nfrom __future__ import absolute_import\n\nimport hashlib\nfrom os import makedirs\nfrom os.path import basename, dirname, exists, isdir, join, relpath\nimport re\nfrom shutil import copy\nimport sys\nfrom tempfile import mkdtemp\nimport webbrowser\n\nfrom docutils import nodes\nfrom docutils.parsers.rst.directives import choice, flag, unchanged\nfrom docutils.statemachine import ViewList\n\nimport jinja2\n\nfrom sphinx.locale import _\nfrom sphinx.util.compat import Directive\n\nfrom .utils import out_of_date\nfrom .. import plotting\nfrom ..document import Document\nfrom ..embed import autoload_static\nfrom ..resources import CDN\nfrom ..utils import decode_utf8\n\n\nSOURCE_TEMPLATE = jinja2.Template(u\"\"\"\n.. code-block:: python\n   {% if linenos %}:linenos:{% endif %}\n   {% if emphasize_lines %}:emphasize-lines: {{ emphasize_lines }}{% endif %}\n\n   {{ source|indent(3) }}\n\n\"\"\")\n\n\nSCRIPT_TEMPLATE = jinja2.Template(u\"\"\"\n<table>\n  <tr>\n    <td>\n    {{ script|indent(4) }}\n    </td>\n  </tr>\n</table>\n\"\"\")\n\n\nclass bokeh_plot(nodes.General, nodes.Element):\n    pass\n\n\ndef _source_position(argument):\n    return choice(argument, ('below', 'above', 'none'))\n\n\nclass BokehPlotDirective(Directive):\n\n    has_content = True\n    optional_arguments = 2\n\n    option_spec = {\n        'source-position' : _source_position,\n        'linenos'         : flag,\n        'emphasize-lines' : unchanged,\n    }\n\n    def run(self):\n        # filename *or* python code content, but not both\n        if self.arguments and self.content:\n            raise RuntimeError(\"bokeh-plot:: directive can't have both args and content\")\n\n        env = self.state.document.settings.env\n        app = env.app\n\n        if not hasattr(env, 'bokeh_plot_tmpdir'):\n            env.bokeh_plot_tmpdir = mkdtemp()\n            app.verbose(\"creating new temp dir for bokeh-plot cache: %s\" % env.bokeh_plot_tmpdir)\n        else:\n            tmpdir = env.bokeh_plot_tmpdir\n            if not exists(tmpdir) or not isdir(tmpdir):\n                app.verbose(\"creating new temp dir for bokeh-plot cache: %s\" % env.bokeh_plot_tmpdir)\n                env.bokeh_plot_tmpdir = mkdtemp()\n            else:\n                app.verbose(\"using existing temp dir for bokeh-plot cache: %s\" % env.bokeh_plot_tmpdir)\n\n        # TODO (bev) verify that this is always the correct thing\n        rst_source = self.state_machine.node.document['source']\n        rst_dir = dirname(rst_source)\n        rst_filename = basename(rst_source)\n\n        target_id = \"%s.bokeh-plot-%d\" % (rst_filename, env.new_serialno('bokeh-plot'))\n        target_node = nodes.target('', '', ids=[target_id])\n        result = [target_node]\n\n        try:\n            source = self._get_source()\n        except Exception:\n            node = nodes.error(None,\n                               nodes.paragraph(text=\"Unable to generate Bokeh plot at %s:%d:\" % (basename(rst_source), self.lineno)),\n                               nodes.paragraph(text=str(sys.exc_info()[1])))\n            return [node]\n\n        source_position = self.options.get('source-position', 'below')\n\n        if source_position == 'above':\n            result += self._get_source_nodes(source)\n\n        node = bokeh_plot()\n        node['target_id'] = target_id\n        node['source'] = source\n        node['relpath'] = relpath(rst_dir, env.srcdir)\n        node['rst_source'] = rst_source\n        node['rst_lineno'] = self.lineno\n        if 'alt' in self.options:\n            node['alt'] = self.options['alt']\n        if self.arguments:\n            node['path'] = self.arguments[0]\n            env.note_dependency(node['path'])\n        if len(self.arguments) == 2:\n            node['symbol'] = self.arguments[1]\n        result += [node]\n\n        if source_position == 'below':\n            result += self._get_source_nodes(source)\n\n        return result\n\n    def _get_source(self):\n        if self.arguments:\n            source = open(self.arguments[0], \"r\").read()\n            source = decode_utf8(source)\n        else:\n            source = u\"\"\n            for line in self.content:\n                source += \"%s\\n\" % line\n        return source\n\n    def _get_source_nodes(self, source):\n        linenos = 'linenos' in self.options\n        emphasize_lines = self.options.get('emphasize-lines', False)\n        if emphasize_lines: linenos = True\n        result = ViewList()\n        text = SOURCE_TEMPLATE.render(source=source, linenos=linenos, emphasize_lines=emphasize_lines)\n        for line in text.split(\"\\n\"):\n            result.append(line, \"<bokeh-plot>\")\n        node = nodes.paragraph()\n        node.document = self.state.document\n        self.state.nested_parse(result, 0, node)\n        return node.children\n\n# patch open and show and save to be no-ops\ndef _noop(*args, **kwargs):\n    pass\n\ndef _show(obj=None):\n    if obj:\n        plotting._obj = obj\n\nwebbrowser.open = _noop\nplotting.save = _noop\nplotting.show = _show\n\ndef _render_plot(source, symbol):\n    plotting._default_document = Document()\n    namespace = {}\n    # need to remove any encoding comment before compiling unicode\n    pat = re.compile(r\"^# -\\*- coding: (.*) -\\*-$\", re.M)\n    source = pat.sub(\"\", source)\n    code = compile(source, \"<string>\", mode=\"exec\")\n    eval(code, namespace)\n    # TODO (bev) remove this crap\n    if symbol is not None:\n        if 'bokeh.charts' in source:\n            obj = namespace[symbol].chart.plot\n        else:\n            obj = namespace[symbol]\n    else:\n        obj = plotting._obj\n    return obj\n\ndef html_visit_bokeh_plot(self, node):\n    env = self.builder.env\n    dest_dir = join(self.builder.outdir, node[\"relpath\"])\n\n    try:\n        if node.has_key('path'):\n            path = node['path']\n            filename = \"bokeh-plot-%s.js\" %  hashlib.md5(path.encode('utf-8')).hexdigest()\n            dest_path = join(dest_dir, filename)\n            tmpdir = join(env.bokeh_plot_tmpdir, node[\"relpath\"])\n            if not exists(tmpdir): makedirs(tmpdir)\n            cached_path = join(tmpdir, filename)\n\n            if out_of_date(path, cached_path) or not exists(cached_path+\".script\"):\n                self.builder.app.verbose(\"generating new plot for '%s'\" % path)\n                plot = _render_plot(node['source'], node.get('symbol'))\n                js, script = autoload_static(plot, CDN, filename)\n                with open(cached_path, \"w\") as f:\n                    f.write(js)\n                with open(cached_path+\".script\", \"w\") as f:\n                    f.write(script)\n            else:\n                self.builder.app.verbose(\"using cached plot for '%s'\" % path)\n                script = open(cached_path+\".script\", \"r\").read()\n\n            if not exists(dest_dir): makedirs(dest_dir)\n            copy(cached_path, dest_path)\n        else:\n            filename = node['target_id'] + \".js\"\n            dest_path = join(dest_dir, filename)\n            plot = _render_plot(node['source'], None)\n            js, script = autoload_static(plot, CDN, filename)\n            self.builder.app.verbose(\"saving inline plot at: %s\" % dest_path)\n            with open(dest_path, \"w\") as f:\n                f.write(js)\n\n        html = SCRIPT_TEMPLATE.render(script=script)\n        self.body.append(html)\n    except Exception:\n        err_node = nodes.error(None,\n                               nodes.paragraph(text=\"Unable to generate Bokeh plot at %s:%d:\" % (node['rst_source'], node['rst_lineno'])),\n                               nodes.paragraph(text=str(sys.exc_info()[1])))\n        node.children.append(err_node)\n        raise nodes.SkipDeparture\n    else:\n        raise nodes.SkipNode\n\n\ndef latex_visit_bokeh_plot(self, node):\n    if 'alt' in node.attributes:\n        self.body.append(_('[graph: %s]') % node['alt'])\n    else:\n        self.body.append(_('[graph]'))\n    raise nodes.SkipNode\n\n\ndef texinfo_visit_bokeh_plot(self, node):\n    if 'alt' in node.attributes:\n        self.body.append(_('[graph: %s]') % node['alt'])\n    else:\n        self.body.append(_('[graph]'))\n    raise nodes.SkipNode\n\n\ndef text_visit_bokeh_plot(self, node):\n    if 'alt' in node.attributes:\n        self.add_text(_('[graph: %s]') % node['alt'])\n    else:\n        self.add_text(_('[graph]'))\n    raise nodes.SkipNode\n\n\ndef man_visit_bokeh_plot(self, node):\n    if 'alt' in node.attributes:\n        self.body.append(_('[graph: %s]') % node['alt'])\n    else:\n        self.body.append(_('[graph]'))\n    raise nodes.SkipNode\n\n\ndef setup(app):\n    app.add_node(bokeh_plot,\n                 html=(html_visit_bokeh_plot, None),\n                 latex=(latex_visit_bokeh_plot, None),\n                 texinfo=(texinfo_visit_bokeh_plot, None),\n                 text=(text_visit_bokeh_plot, None),\n                 man=(man_visit_bokeh_plot, None))\n    app.add_directive('bokeh-plot', BokehPlotDirective)\n\n\n\n\n\n\n", "path": "bokeh/sphinxext/bokeh_plot.py"}], "after_files": [{"content": "\"\"\" Include Bokeh plots in Sphinx HTML documentation.\n\nFor other output types, the placeholder text ``[graph]`` will\nbe generated.\n\nUsage\n-----\n\nThe ``bokeh-plot`` directive can be used by either supplying:\n\n1. **A path to a source file** as the argument to the directive::\n\n    .. bokeh-plot:: path/to/plot.py\n\n\n2. **Inline code** as the content of the directive::\n\n    .. bokeh-plot::\n\n        from bokeh.plotting import figure, output_file, show\n\n        output_file(\"example.html\")\n\n        x = [1, 2, 3, 4, 5]\n        y = [6, 7, 6, 4, 5]\n\n        p = figure(title=\"example\", plot_width=300, plot_height=300)\n        p.line(x, y, line_width=2)\n        p.circle(x, y, size=10, fill_color=\"white\")\n\n        show(p)\n\nThis directive also works in conjunction with Sphinx autodoc, when\nused in docstrings.\n\nOptions\n-------\n\nThe ``bokeh-plot`` directive accepts the following options:\n\nsource-position : enum('above', 'below', 'none')\n    Where to locate the the block of formatted source\n    code (if anywhere).\n\nlinenos : bool\n    Whether to display line numbers along with the source.\n\nemphasize-lines : list[int]\n    A list of source code lines to emphasize.\n\nExamples\n--------\n\nThe inline example code above produces the following output:\n\n----\n\n.. bokeh-plot::\n\n    from bokeh.plotting import figure, output_file, show\n\n    output_file(\"example.html\")\n\n    x = [1, 2, 3, 4, 5]\n    y = [6, 7, 6, 4, 5]\n\n    p = figure(title=\"example\", plot_width=300, plot_height=300)\n    p.line(x, y, line_width=2)\n    p.circle(x, y, size=10, fill_color=\"white\")\n\n    show(p)\n\n\"\"\"\nfrom __future__ import absolute_import\n\nimport hashlib\nfrom os import makedirs\nfrom os.path import basename, dirname, exists, isdir, join, relpath\nimport re\nfrom shutil import copy\nimport sys\nfrom tempfile import mkdtemp\nimport webbrowser\n\nfrom docutils import nodes\nfrom docutils.parsers.rst.directives import choice, flag, unchanged\nfrom docutils.statemachine import ViewList\n\nimport jinja2\n\nfrom sphinx.locale import _\nfrom sphinx.util.compat import Directive\n\nfrom .utils import out_of_date\nfrom .. import charts, io, plotting\nfrom ..document import Document\nfrom ..embed import autoload_static\nfrom ..resources import CDN\nfrom ..utils import decode_utf8\n\n\nSOURCE_TEMPLATE = jinja2.Template(u\"\"\"\n.. code-block:: python\n   {% if linenos %}:linenos:{% endif %}\n   {% if emphasize_lines %}:emphasize-lines: {{ emphasize_lines }}{% endif %}\n\n   {{ source|indent(3) }}\n\n\"\"\")\n\n\nSCRIPT_TEMPLATE = jinja2.Template(u\"\"\"\n<table>\n  <tr>\n    <td>\n    {{ script|indent(4) }}\n    </td>\n  </tr>\n</table>\n\"\"\")\n\n\nclass bokeh_plot(nodes.General, nodes.Element):\n    pass\n\n\ndef _source_position(argument):\n    return choice(argument, ('below', 'above', 'none'))\n\n\nclass BokehPlotDirective(Directive):\n\n    has_content = True\n    optional_arguments = 2\n\n    option_spec = {\n        'source-position' : _source_position,\n        'linenos'         : flag,\n        'emphasize-lines' : unchanged,\n    }\n\n    def run(self):\n        # filename *or* python code content, but not both\n        if self.arguments and self.content:\n            raise RuntimeError(\"bokeh-plot:: directive can't have both args and content\")\n\n        env = self.state.document.settings.env\n        app = env.app\n\n        if not hasattr(env, 'bokeh_plot_tmpdir'):\n            env.bokeh_plot_tmpdir = mkdtemp()\n            app.verbose(\"creating new temp dir for bokeh-plot cache: %s\" % env.bokeh_plot_tmpdir)\n        else:\n            tmpdir = env.bokeh_plot_tmpdir\n            if not exists(tmpdir) or not isdir(tmpdir):\n                app.verbose(\"creating new temp dir for bokeh-plot cache: %s\" % env.bokeh_plot_tmpdir)\n                env.bokeh_plot_tmpdir = mkdtemp()\n            else:\n                app.verbose(\"using existing temp dir for bokeh-plot cache: %s\" % env.bokeh_plot_tmpdir)\n\n        # TODO (bev) verify that this is always the correct thing\n        rst_source = self.state_machine.node.document['source']\n        rst_dir = dirname(rst_source)\n        rst_filename = basename(rst_source)\n\n        target_id = \"%s.bokeh-plot-%d\" % (rst_filename, env.new_serialno('bokeh-plot'))\n        target_node = nodes.target('', '', ids=[target_id])\n        result = [target_node]\n\n        try:\n            source = self._get_source()\n        except Exception:\n            node = nodes.error(None,\n                               nodes.paragraph(text=\"Unable to generate Bokeh plot at %s:%d:\" % (basename(rst_source), self.lineno)),\n                               nodes.paragraph(text=str(sys.exc_info()[1])))\n            return [node]\n\n        source_position = self.options.get('source-position', 'below')\n\n        if source_position == 'above':\n            result += self._get_source_nodes(source)\n\n        node = bokeh_plot()\n        node['target_id'] = target_id\n        node['source'] = source\n        node['relpath'] = relpath(rst_dir, env.srcdir)\n        node['rst_source'] = rst_source\n        node['rst_lineno'] = self.lineno\n        if 'alt' in self.options:\n            node['alt'] = self.options['alt']\n        if self.arguments:\n            node['path'] = self.arguments[0]\n            env.note_dependency(node['path'])\n        if len(self.arguments) == 2:\n            node['symbol'] = self.arguments[1]\n        result += [node]\n\n        if source_position == 'below':\n            result += self._get_source_nodes(source)\n\n        return result\n\n    def _get_source(self):\n        if self.arguments:\n            source = open(self.arguments[0], \"r\").read()\n            source = decode_utf8(source)\n        else:\n            source = u\"\"\n            for line in self.content:\n                source += \"%s\\n\" % line\n        return source\n\n    def _get_source_nodes(self, source):\n        linenos = 'linenos' in self.options\n        emphasize_lines = self.options.get('emphasize-lines', False)\n        if emphasize_lines: linenos = True\n        result = ViewList()\n        text = SOURCE_TEMPLATE.render(source=source, linenos=linenos, emphasize_lines=emphasize_lines)\n        for line in text.split(\"\\n\"):\n            result.append(line, \"<bokeh-plot>\")\n        node = nodes.paragraph()\n        node.document = self.state.document\n        self.state.nested_parse(result, 0, node)\n        return node.children\n\n# patch open and show and save to be no-ops\ndef _noop(*args, **kwargs):\n    pass\n\ndef _show(obj=None):\n    if obj:\n        plotting._obj = obj\n\nwebbrowser.open = _noop\ncharts.save = _noop\ncharts.show = _show\nio.save = _noop\nio.show = _show\nplotting.save = _noop\nplotting.show = _show\n\ndef _render_plot(source, symbol):\n    plotting._default_document = Document()\n    namespace = {}\n    # need to remove any encoding comment before compiling unicode\n    pat = re.compile(r\"^# -\\*- coding: (.*) -\\*-$\", re.M)\n    source = pat.sub(\"\", source)\n    code = compile(source, \"<string>\", mode=\"exec\")\n    eval(code, namespace)\n    # TODO (bev) remove this crap\n    if symbol is not None:\n        if 'bokeh.charts' in source:\n            obj = namespace[symbol].chart.plot\n        else:\n            obj = namespace[symbol]\n    else:\n        obj = plotting._obj\n    return obj\n\ndef html_visit_bokeh_plot(self, node):\n    env = self.builder.env\n    dest_dir = join(self.builder.outdir, node[\"relpath\"])\n\n    try:\n        if node.has_key('path'):\n            path = node['path']\n            filename = \"bokeh-plot-%s.js\" %  hashlib.md5(path.encode('utf-8')).hexdigest()\n            dest_path = join(dest_dir, filename)\n            tmpdir = join(env.bokeh_plot_tmpdir, node[\"relpath\"])\n            if not exists(tmpdir): makedirs(tmpdir)\n            cached_path = join(tmpdir, filename)\n\n            if out_of_date(path, cached_path) or not exists(cached_path+\".script\"):\n                self.builder.app.verbose(\"generating new plot for '%s'\" % path)\n                plot = _render_plot(node['source'], node.get('symbol'))\n                js, script = autoload_static(plot, CDN, filename)\n                with open(cached_path, \"w\") as f:\n                    f.write(js)\n                with open(cached_path+\".script\", \"w\") as f:\n                    f.write(script)\n            else:\n                self.builder.app.verbose(\"using cached plot for '%s'\" % path)\n                script = open(cached_path+\".script\", \"r\").read()\n\n            if not exists(dest_dir): makedirs(dest_dir)\n            copy(cached_path, dest_path)\n        else:\n            filename = node['target_id'] + \".js\"\n            dest_path = join(dest_dir, filename)\n            plot = _render_plot(node['source'], None)\n            js, script = autoload_static(plot, CDN, filename)\n            self.builder.app.verbose(\"saving inline plot at: %s\" % dest_path)\n            with open(dest_path, \"w\") as f:\n                f.write(js)\n\n        html = SCRIPT_TEMPLATE.render(script=script)\n        self.body.append(html)\n    except Exception:\n        err_node = nodes.error(None,\n                               nodes.paragraph(text=\"Unable to generate Bokeh plot at %s:%d:\" % (node['rst_source'], node['rst_lineno'])),\n                               nodes.paragraph(text=str(sys.exc_info()[1])))\n        node.children.append(err_node)\n        raise nodes.SkipDeparture\n    else:\n        raise nodes.SkipNode\n\n\ndef latex_visit_bokeh_plot(self, node):\n    if 'alt' in node.attributes:\n        self.body.append(_('[graph: %s]') % node['alt'])\n    else:\n        self.body.append(_('[graph]'))\n    raise nodes.SkipNode\n\n\ndef texinfo_visit_bokeh_plot(self, node):\n    if 'alt' in node.attributes:\n        self.body.append(_('[graph: %s]') % node['alt'])\n    else:\n        self.body.append(_('[graph]'))\n    raise nodes.SkipNode\n\n\ndef text_visit_bokeh_plot(self, node):\n    if 'alt' in node.attributes:\n        self.add_text(_('[graph: %s]') % node['alt'])\n    else:\n        self.add_text(_('[graph]'))\n    raise nodes.SkipNode\n\n\ndef man_visit_bokeh_plot(self, node):\n    if 'alt' in node.attributes:\n        self.body.append(_('[graph: %s]') % node['alt'])\n    else:\n        self.body.append(_('[graph]'))\n    raise nodes.SkipNode\n\n\ndef setup(app):\n    app.add_node(bokeh_plot,\n                 html=(html_visit_bokeh_plot, None),\n                 latex=(latex_visit_bokeh_plot, None),\n                 texinfo=(texinfo_visit_bokeh_plot, None),\n                 text=(text_visit_bokeh_plot, None),\n                 man=(man_visit_bokeh_plot, None))\n    app.add_directive('bokeh-plot', BokehPlotDirective)\n\n\n\n\n\n\n", "path": "bokeh/sphinxext/bokeh_plot.py"}]}