Repository: mkdocs/mkdocs

Issue:
Unable to add Table of Contents to docs
When I build a markdown file containing the following information with, `mkdocs build --clean`, mkdocs throws:  `AttributeError: 'Markdown' object has no attribute 'toc'`. Adding `[TOC]` like this was working before, but for some reason its throwing an exception now. I'm running version `0.11.1`.

Markdown file:

``` markdown
For api overview and usages, check out [this page](overview.md).

[TOC]

Auth
=================================================

## Check if user is registered

`POST` `/auth/is_registered`

**paramaters**

- `email`

## Login

`POST` `/auth`

**Parameters**

- `email`
- `password`

**Response**

The response will be something like this:
```

Stack Trace:

``` bash
Traceback (most recent call last):
"/usr/local/Cellar/python/2.7.8_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in __bootstrap_inner
    self.run()
  File "/Users/administrator/dev/meet-web/venv/lib/python2.7/site-packages/watchdog/observers/api.py", line 199, in run
    self.dispatch_events(self.event_queue, self.timeout)
  File "/Users/administrator/dev/meet-web/venv/lib/python2.7/site-packages/watchdog/observers/api.py", line 368, in dispatch_events
    handler.dispatch(event)
  File "/Users/administrator/dev/meet-web/venv/lib/python2.7/site-packages/watchdog/events.py", line 322, in dispatch
    self.on_any_event(event)
  File "/Users/administrator/dev/meet-web/venv/lib/python2.7/site-packages/mkdocs/serve.py", line 28, in on_any_event
    build(config, live_server=True)
  File "/Users/administrator/dev/meet-web/venv/lib/python2.7/site-packages/mkdocs/build.py", line 223, in build
    build_pages(config)
  File "/Users/administrator/dev/meet-web/venv/lib/python2.7/site-packages/mkdocs/build.py", line 170, in build_pages
    extensions=config['markdown_extensions'], strict=config['strict']
  File "/Users/administrator/dev/meet-web/venv/lib/python2.7/site-packages/mkdocs/build.py", line 36, in convert_markdown
    toc_html = md.toc
AttributeError: 'Markdown' object has no attribute 'toc'
```



Discussion:
Would you be able to show what `pip freeze` gives for the project? (I think you're using Virtualenv under Windows, right?)

Any chance the project is publicly available to glance over?

@shakna-israel Thanks for taking a look. I'm using virtualenv in OSX, here's my pip freeze:

``` python
Django==1.7.4
Jinja2==2.7.3
Markdown==2.4.1
MarkupSafe==0.23
Pillow==2.7.0
PyJWT==0.4.1
PyYAML==3.11
Unidecode==0.04.17
Werkzeug==0.9.6
argh==0.26.1
arrow==0.5.0
bumpversion==0.5.1
click==3.3
coverage==4.0a4
dj-database-url==0.3.0
django-autoslug==1.7.2
django-configurations==0.8
django-debug-toolbar==1.2.2
django-emailtools==0.2.2
django-extensions==1.4.9
django-grappelli==2.6.3
django-model-utils==2.2
django-rq==0.7.0
django-secure==1.0.1
django-sites==0.8
django-user-agents==0.3.0
django-uuid-upload-path==1.0.0
django-versatileimagefield==0.5.1
djangorestframework==3.0.4
execnet==1.3.0
factory-boy==2.4.1
flake8==2.3.0
ghp-import==0.4.1
gnureadline==6.3.3
ipdb==0.8
ipython==2.3.1
jsonfield==1.0.3
mccabe==0.3
mkdocs==0.11.1
mock==1.0.1
pathtools==0.1.2
pep8==1.6.2
psycopg2==2.5.4
py==1.4.26
pyflakes==0.8.1
pygraphviz==1.3rc2
pytest==2.6.4
pytest-cache==1.0
pytest-django==2.8.0
pytest-flakes==0.2
pytest-ipdb==0.1-prerelease2
pytest-pythonpath==0.6
python-dateutil==2.4.1
python-dotenv==0.1.0
pytz==2014.10
redis==2.10.3
requests==2.5.1
responses==0.3.0
rq==0.5.1
six==1.9.0
sqlparse==0.1.14
ua-parser==0.3.6
unicode-slugify==0.1.3
user-agents==0.3.1
watchdog==0.8.3
wsgiref==0.1.2
```

Would you be able to try against git master? As it happens, the toc code was refactored a bit. If that doesn't work, I'll dig deeper. If it does, I'm trying to do a release soon.

hmm, actually, that traceback looks like it is the new code (and thus git master and not 0.11.1). We need to update master to reflect it is a dev version - that is partyl our fault. Anyway, the line the exception is happening on isn't in 0.11.1 :) - so this is a regression with the refactor. I'll take a look.

Okay, I've done some investigation into this. This is a tricky one, the problem is, that MkDocs uses the toc extension to build up the navigation and so on. We didn't really anticipate users using the extension too.

I can't see an obvious way that will make this work for both of us.

Actually the fix for this is to support Python-Markdown version 2.6. In that version, a [refactor](https://pythonhosted.org/Markdown/release-2.6.html#table-of-contents-extension-refactored) of the TOC extension includes always providing the `toc` attribute on the class, even when a "marker" is found in the document. AFAICT, this has always been an issue with mkdocs. I assume this problem will fix itself when [Python 2.6 support is dropped](https://github.com/mkdocs/mkdocs/issues/165) (which, as I understand it, is the only reason mkdocs currently does not support Python-Markdown 2.6).

@agconti if you are on Pytthon > 2.6 you might what to try forcing an upgrade of Python-Markdown:

```
pip install -U markdown
```

You just have to do this after installing mkdocs, as the mkdocs install script specifically states that it requires version <2.5.

@waylan, thanks for looking into this. I'll try this tomorrow and will get back to you.

@waylan upgrading markdown after mkdocs is installed is throwing the following error when `mkdocs build --clean` is executed: 

``` shell
pkg_resources.DistributionNotFound: Markdown>=2.3.1,<2.5
```

Is there a way to get around this other than trying to upgrade markdown after mkdocs is installed? 

Stack Trace:

``` shell
Traceback (most recent call last):
  File "/Users/administrator/dev/meet-web/venv/bin/mkdocs", line 5, in <module>
    from pkg_resources import load_entry_point
  File "/Users/administrator/dev/meet-web/venv/lib/python2.7/site-packages/pkg_resources.py", line 2829, in <module>
    working_set = WorkingSet._build_master()
  File "/Users/administrator/dev/meet-web/venv/lib/python2.7/site-packages/pkg_resources.py", line 451, in _build_master
    return cls._build_from_requirements(__requires__)
  File "/Users/administrator/dev/meet-web/venv/lib/python2.7/site-packages/pkg_resources.py", line 464, in _build_from_requirements
    dists = ws.resolve(reqs, Environment())
  File "/Users/administrator/dev/meet-web/venv/lib/python2.7/site-packages/pkg_resources.py", line 639, in resolve
    raise DistributionNotFound(req)
pkg_resources.DistributionNotFound: Markdown>=2.3.1,<2.5
```

That's annoying, I didn't realise it would block you doing that.

You could fork and change this line temporarily :) https://github.com/mkdocs/mkdocs/blob/master/setup.py#L22

I was afraid of that. I couldn't remember for sure yesterday, but when Setuptools installs a package, it remembers that packages "requirements" and makes sure those requirements are met every time you try to use that package. Well, at least every time you try to use that package through Setuptools, which happens with the command line scripts as they are defined as "entry_points" through Setuptools.

You could try modifying mkdocs' `setup.py` file by changing [line 22](https://github.com/mkdocs/mkdocs/blob/master/setup.py#L22) from:

``` python
'Markdown>=2.3.1,<2.5',
```

to 

``` python
'Markdown',
```

Then reinstall your local copy of mkdocs.

@d0ugal you could include a conditional in the setup.py script which only added the `'<2.5'` restriction if the Python version is 2.6. Then this bug could be fixed (by upgrading markdown) in any supported version of Python except 2.6.. Just a suggestion. I realize this restriction will likely go away real soon as it appears that 0.12 is about to be released. But you might like not having this bug in 0.12 if you can.


Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -7,6 +7,8 @@
 import os
 import sys
 
+PY26 = sys.version_info[:2] == (2, 6)
+
 
 name = 'mkdocs'
 package = 'mkdocs'
@@ -16,11 +18,11 @@
 author_email = 'tom@tomchristie.com'
 license = 'BSD'
 install_requires = [
+    'ghp-import>=0.4.1',
     'Jinja2>=2.7.1',
-    'Markdown>=2.3.1,<2.5',
+    'Markdown>=2.3.1,<2.5' if PY26 else 'Markdown>=2.3.1',
     'PyYAML>=3.10',
     'watchdog>=0.7.0',
-    'ghp-import>=0.4.1'
 ]
 
 long_description = (


Test patch: