Skip to content
Browse files

adding table of contents to the doc menus.

  • Loading branch information...
1 parent a5ea821 commit 3a173e3747c8686321483cbe706a1dfa157540ca @anutron committed Jun 28, 2011
View
111 frontend_dev/templates/left_menu.mako
@@ -1,12 +1,11 @@
-<%def name="print_toc(toc)">
- % for item in toc:
- <%
- klass = ""
- if ":" not in item:
- klass = "toc_section"
- %>
- <li class="toc ${klass}"><a href="#${item}">${item}</a></li>
- % endfor
+<%def name="print_toc(toc, file_path = '')">
+ <ul class="toc">
+ % for item in toc:
+ % if ':' in item:
+ <li class="toc toc_section"><a target="content" href="${file_path}#${item}">${item.split(':')[1]}</a></li>
+ % endif
+ % endfor
+ </ul>
</%def>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
@@ -52,11 +51,60 @@
ac.hideChoices();
filter.value = '';
filter.blur.delay(20, $('filter'));
+ select(term_map[value])
}
});
filter.addEvent('blur', function(){
filter.value = '';
});
+
+ var scrollTo = function(li){
+ scroller.start(0, document.id(li).getPosition(document.body).y - 40);
+ };
+
+ var select = function(link){
+ var toc = $$('.toc')[0];
+ var li = link.getParent('li').addClass('mt-selected');
+ if (toc) {
+ toc.dissolve().get('reveal').chain(function(){
+ toc.destroy();
+ scrollTo(li);
+ });
+ }
+ getTOC(link);
+ };
+
+ var scroller = new Fx.Scroll(document.body);
+
+ $$('.mt-nav')[0].addEvent('click:relay(a.doc)', function(e, link){
+ select(link);
+ });
+
+ var getTOC = function(link){
+ $$('.mt-selected').removeClass('mt-selected');
+ var li = link.getParent('li').addClass('mt-selected');
+ new Request.HTML({
+ spinnerTarget: li,
+ useSpinner: true,
+ spinnerOptions: {
+ containerPosition: {
+ position: 'upperRight',
+ edge: 'centerRight',
+ offset: {
+ y: 4
+ }
+ }
+ },
+ url:'/toc' + link.get('href').replace('viewdoc/', ''),
+ onComplete: function(responseTree, responseElements, responseHTML, responseJavaScript){
+ var toc = Elements.from(responseHTML)[0];
+ toc.hide().inject(link, 'after').reveal();
+ },
+ data: {basepath: link.get('href')}
+ }).send();
+ };
+ var currentTOC = $$('.toc')[0];
+ if (!currentTOC) getTOC($$('a.doc')[0]);
});
</script>
</head>
@@ -66,26 +114,31 @@
<div id="filter_wrapper"><input id="filter" title="Search"></div>
% if projects is not None:
% for project, directories in sorted(projects.items()):
- % if not excluded_tests or project not in excluded_tests:
- <h2>${project}</h2>
- % for directory in sorted(directories):
- <dl class="mt-tests">
- % if len(directory['title'].strip()) > 0 and directory['subdir'] != '.':
- <dt>${directory['title']}</dt>
- % endif
- <dd>
- <ul>
- % for file_path, file_title in sorted(directory['file_dict'].items(), key=lambda x: x[1].lower()):
- <li><span></span><a target="content" href="${file_path}">${file_title}</a></li>
- % if toc and klass is not "":
- ${print_toc(toc)}
- % endif
- % endfor
- </ul>
- </dd>
- </dl>
- % endfor
- % endif
+ <h2>${project}</h2>
+ % for directory in sorted(directories):
+ <dl class="mt-tests">
+ % if len(directory['title'].strip()) > 0 and directory['subdir'] != '.':
+ <dt>${directory['title']}</dt>
+ % endif
+ <dd>
+ <ul>
+ % for file_path, file_title in sorted(directory['file_dict'].items(), key=lambda x: x[1].lower()):
+ <%
+ klass = ''
+ if current_project == project and current_path == file_path.split('/')[-1]:
+ klass = 'mt-selected'
+ %>
+ <li class="${klass}">
+ <span></span><a target="content" class="doc" href="${file_path}">${file_title}</a>
+ % if klass != '' and toc:
+ ${print_toc(toc, file_path)}
+ % endif
+ </li>
+ % endfor
+ </ul>
+ </dd>
+ </dl>
+ % endfor
% endfor
% endif
</div>
View
3 frontend_dev/templates/markdown.mako
@@ -1,4 +1,6 @@
<%namespace name="components" file="demo_components.mako" />
+<%namespace name="menu" file="left_menu.mako" />
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
@@ -8,6 +10,7 @@
</head>
<body>
<div class="markdown">
+ <a name="top"></a>
${body}
</div>
</body>
View
2 frontend_dev/templates/toc.mako
@@ -0,0 +1,2 @@
+<%namespace name="menu" file="left_menu.mako" />
+ ${menu.print_toc(toc, basepath)}
View
4 frontend_dev/urls.py
@@ -8,11 +8,13 @@
(r'^welcome/', 'views.welcome'),
(r'^demo_menu/', 'views.demo_menu'),
- (r'^docs_menu/', 'views.docs_menu'),
+ (r'^docs_menu/$', 'views.docs_menu'),
+ (r'^docs_menu/(?P<project>(\w|-|_)+)/(?P<path>.*)$', 'views.docs_menu'),
(r'^docs/(?P<project>(\w|-|_)+)/(?P<path>.*)$', 'views.docs'),
(r'^viewdoc/(?P<path>.*)$', 'views.viewdoc'),
+ (r'^toc/(?P<path>.*)$', 'views.toc'),
(r'^source/', 'views.view_source'),
(r'^demo/', 'views.demo'),
(r'^specs/', 'views.specs'),
View
72 frontend_dev/views.py
@@ -47,7 +47,7 @@ def index(request, path=False, content_path=False):
)
def docs(request, project, path):
- return index(request, content_path = '/viewdoc/' + project + '/Docs/' + path)
+ return index(request, path = '/bottom_frame?menu_path=/docs_menu/' + project + '/' + path + '&content_path=/viewdoc/' + project + '/Docs/' + path)
def welcome(request):
""" The default 'home' page for the main content frame; pulls in WELCOME.md from the frontend_dev app. """
@@ -224,29 +224,12 @@ def format_code(extension, code_str):
# DOCS
def viewdoc(request, path):
- if path == '':
- path = "test-runner/WELCOME"
- if not re.search("md$(?i)", path):
- path = path + '.md'
- text = None
- if '..' in path:
- raise Exception('invalid path: %s' % path)
- else:
- md = os.path.abspath(os.path.join(settings.DOC_ROOT, '../', path))
- if os.path.isfile(md):
- text = open(md, 'rb').read()
- if text is None:
- raise Exception("The path %s was not found." % path)
- else:
- parsed = markdown(text)
+ parsed, path = _read_md(path)
dirs, files = get_docs_files()
-
- toc = []
-
+
def replacer(matchobj):
match = matchobj.group(0)
match = re.sub('\{#|}', '', match)
- toc.append(match)
return '<a class="toc_anchor" name="' + match + '"></a><a href="#top" class="to_top">back to top</a>'
parsed = re.sub("\{#.*?}", replacer, parsed)
@@ -259,10 +242,42 @@ def replacer(matchobj):
'title_prefix': settings.TITLE_PREFIX,
'current': 'viewdoc/' + path,
'dirs': dirs,
- 'toc': toc
+ 'toc': get_toc(parsed)
}
)
+def _fix_md_extension(path):
+ if not re.search("md$(?i)", path):
+ path = path + '.md'
+ return path
+
+def _read_md(path):
+ if path == '':
+ path = "test-runner/WELCOME"
+ path = _fix_md_extension(path)
+
+ text = None
+ if '..' in path:
+ raise Exception('invalid path: %s' % path)
+ else:
+ md = os.path.abspath(os.path.join(settings.DOC_ROOT, '../', path))
+ if os.path.isfile(md):
+ text = open(md, 'rb').read()
+ if text is None:
+ raise Exception("The path %s was not found." % path)
+ else:
+ return (markdown(text), path)
+
+def get_toc(content):
+ return re.findall("\{#(.*?)}", content)
+
+def toc(request, path):
+ toc = get_toc(_read_md(path)[0])
+ basepath = request.REQUEST.get('basepath')
+ return render_to_response('toc.mako',{
+ 'basepath': basepath,
+ 'toc': toc
+ })
# NAVIGATION
def top_nav(request):
@@ -291,13 +306,26 @@ def demo_menu(request):
'title': 'Demos',
}
)
-def docs_menu(request):
+def docs_menu(request, project=None, path=None):
""" Renders a menu with a list of all available docs. """
projects, dir_map = get_docs_files()
+
+ if project and path:
+ path = _fix_md_extension(path)
+ file_path = get_path(settings.PROJECTS[project]['docs']) + '/' + path
+ toc = get_toc(_read_md(file_path)[0])
+ else:
+ path = None
+ file_path = None
+ toc = None
+
return render_to_response('left_menu.mako',
{
'projects': projects,
'title': 'Docs',
+ 'current_project': project,
+ 'current_path': path,
+ 'toc': toc
}
)
View
BIN static/art/docs-spinner.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN static/art/spinner.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
26 static/css/left_menu.css
@@ -11,7 +11,9 @@ h1 {
font-size: 16px;
font-weight: bold;
padding: 4px;
- margin: 0;
+ margin: 0 0 8px 0;
+ position:relative;
+ top: 32px;
}
h2 {
font-weight: bold;
@@ -62,12 +64,15 @@ a:hover {
}
#filter_wrapper {
+ width: 100%;
font-size: 14px;
background: #D3E0ED;
font-weight: bold;
- position: relative;
- margin: 0px -8px 8px;
border-bottom: 1px solid #aaa;
+ position: fixed;
+ top: 0px;
+ left: 0px;
+ z-index:1;
}
#filter {
background-color: #D3E0ED;
@@ -93,6 +98,9 @@ label {
}
/* docs */
+ul {
+ position: relative;
+}
ul li.toc {
margin-left: 20px;
}
@@ -105,4 +113,14 @@ ul li.toc a {
ul li.toc_section a {
font-weight: bold;
border-bottom: 1px solid #5B618F;
-}
+}
+
+.spinner {
+ position: absolute;
+}
+.spinner-img {
+ background: url(../art/docs-spinner.gif) no-repeat;
+ width: 24px;
+ height: 24px;
+ margin: 0 auto;
+}

0 comments on commit 3a173e3

Please sign in to comment.
Something went wrong with that request. Please try again.