Skip to content

Commit

Permalink
adding table of contents to the doc menus.
Browse files Browse the repository at this point in the history
  • Loading branch information
anutron committed Jun 28, 2011
1 parent a5ea821 commit 3a173e3
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 56 deletions.
111 changes: 82 additions & 29 deletions frontend_dev/templates/left_menu.mako
@@ -1,12 +1,11 @@
<%def name="print_toc(toc)"> <%def name="print_toc(toc, file_path = '')">
% for item in toc: <ul class="toc">
<% % for item in toc:
klass = "" % if ':' in item:
if ":" not in item: <li class="toc toc_section"><a target="content" href="${file_path}#${item}">${item.split(':')[1]}</a></li>
klass = "toc_section" % endif
%> % endfor
<li class="toc ${klass}"><a href="#${item}">${item}</a></li> </ul>
% endfor
</%def> </%def>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
Expand Down Expand Up @@ -52,11 +51,60 @@
ac.hideChoices(); ac.hideChoices();
filter.value = ''; filter.value = '';
filter.blur.delay(20, $('filter')); filter.blur.delay(20, $('filter'));
select(term_map[value])
} }
}); });
filter.addEvent('blur', function(){ filter.addEvent('blur', function(){
filter.value = ''; 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> </script>
</head> </head>
Expand All @@ -66,26 +114,31 @@
<div id="filter_wrapper"><input id="filter" title="Search"></div> <div id="filter_wrapper"><input id="filter" title="Search"></div>
% if projects is not None: % if projects is not None:
% for project, directories in sorted(projects.items()): % for project, directories in sorted(projects.items()):
% if not excluded_tests or project not in excluded_tests: <h2>${project}</h2>
<h2>${project}</h2> % for directory in sorted(directories):
% for directory in sorted(directories): <dl class="mt-tests">
<dl class="mt-tests"> % if len(directory['title'].strip()) > 0 and directory['subdir'] != '.':
% if len(directory['title'].strip()) > 0 and directory['subdir'] != '.': <dt>${directory['title']}</dt>
<dt>${directory['title']}</dt> % endif
% endif <dd>
<dd> <ul>
<ul> % for file_path, file_title in sorted(directory['file_dict'].items(), key=lambda x: x[1].lower()):
% 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> klass = ''
% if toc and klass is not "": if current_project == project and current_path == file_path.split('/')[-1]:
${print_toc(toc)} klass = 'mt-selected'
% endif %>
% endfor <li class="${klass}">
</ul> <span></span><a target="content" class="doc" href="${file_path}">${file_title}</a>
</dd> % if klass != '' and toc:
</dl> ${print_toc(toc, file_path)}
% endfor % endif
% endif </li>
% endfor
</ul>
</dd>
</dl>
% endfor
% endfor % endfor
% endif % endif
</div> </div>
Expand Down
3 changes: 3 additions & 0 deletions frontend_dev/templates/markdown.mako
@@ -1,4 +1,6 @@
<%namespace name="components" file="demo_components.mako" /> <%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"> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html> <html>
<head> <head>
Expand All @@ -8,6 +10,7 @@
</head> </head>
<body> <body>
<div class="markdown"> <div class="markdown">
<a name="top"></a>
${body} ${body}
</div> </div>
</body> </body>
Expand Down
2 changes: 2 additions & 0 deletions frontend_dev/templates/toc.mako
@@ -0,0 +1,2 @@
<%namespace name="menu" file="left_menu.mako" />
${menu.print_toc(toc, basepath)}
4 changes: 3 additions & 1 deletion frontend_dev/urls.py
Expand Up @@ -8,11 +8,13 @@


(r'^welcome/', 'views.welcome'), (r'^welcome/', 'views.welcome'),
(r'^demo_menu/', 'views.demo_menu'), (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'^docs/(?P<project>(\w|-|_)+)/(?P<path>.*)$', 'views.docs'),


(r'^viewdoc/(?P<path>.*)$', 'views.viewdoc'), (r'^viewdoc/(?P<path>.*)$', 'views.viewdoc'),
(r'^toc/(?P<path>.*)$', 'views.toc'),
(r'^source/', 'views.view_source'), (r'^source/', 'views.view_source'),
(r'^demo/', 'views.demo'), (r'^demo/', 'views.demo'),
(r'^specs/', 'views.specs'), (r'^specs/', 'views.specs'),
Expand Down
72 changes: 50 additions & 22 deletions frontend_dev/views.py
Expand Up @@ -47,7 +47,7 @@ def index(request, path=False, content_path=False):
) )


def docs(request, project, path): 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): def welcome(request):
""" The default 'home' page for the main content frame; pulls in WELCOME.md from the frontend_dev app. """ """ The default 'home' page for the main content frame; pulls in WELCOME.md from the frontend_dev app. """
Expand Down Expand Up @@ -224,29 +224,12 @@ def format_code(extension, code_str):


# DOCS # DOCS
def viewdoc(request, path): def viewdoc(request, path):
if path == '': parsed, path = _read_md(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)
dirs, files = get_docs_files() dirs, files = get_docs_files()


toc = []

def replacer(matchobj): def replacer(matchobj):
match = matchobj.group(0) match = matchobj.group(0)
match = re.sub('\{#|}', '', match) 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>' return '<a class="toc_anchor" name="' + match + '"></a><a href="#top" class="to_top">back to top</a>'


parsed = re.sub("\{#.*?}", replacer, parsed) parsed = re.sub("\{#.*?}", replacer, parsed)
Expand All @@ -259,10 +242,42 @@ def replacer(matchobj):
'title_prefix': settings.TITLE_PREFIX, 'title_prefix': settings.TITLE_PREFIX,
'current': 'viewdoc/' + path, 'current': 'viewdoc/' + path,
'dirs': dirs, '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 # NAVIGATION
def top_nav(request): def top_nav(request):
Expand Down Expand Up @@ -291,13 +306,26 @@ def demo_menu(request):
'title': 'Demos', 'title': 'Demos',
} }
) )
def docs_menu(request): def docs_menu(request, project=None, path=None):
""" Renders a menu with a list of all available docs. """ """ Renders a menu with a list of all available docs. """
projects, dir_map = get_docs_files() 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', return render_to_response('left_menu.mako',
{ {
'projects': projects, 'projects': projects,
'title': 'Docs', 'title': 'Docs',
'current_project': project,
'current_path': path,
'toc': toc
} }
) )


Expand Down
Binary file added 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.
Binary file added 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.
26 changes: 22 additions & 4 deletions static/css/left_menu.css
Expand Up @@ -11,7 +11,9 @@ h1 {
font-size: 16px; font-size: 16px;
font-weight: bold; font-weight: bold;
padding: 4px; padding: 4px;
margin: 0; margin: 0 0 8px 0;
position:relative;
top: 32px;
} }
h2 { h2 {
font-weight: bold; font-weight: bold;
Expand Down Expand Up @@ -62,12 +64,15 @@ a:hover {
} }


#filter_wrapper { #filter_wrapper {
width: 100%;
font-size: 14px; font-size: 14px;
background: #D3E0ED; background: #D3E0ED;
font-weight: bold; font-weight: bold;
position: relative;
margin: 0px -8px 8px;
border-bottom: 1px solid #aaa; border-bottom: 1px solid #aaa;
position: fixed;
top: 0px;
left: 0px;
z-index:1;
} }
#filter { #filter {
background-color: #D3E0ED; background-color: #D3E0ED;
Expand All @@ -93,6 +98,9 @@ label {
} }


/* docs */ /* docs */
ul {
position: relative;
}
ul li.toc { ul li.toc {
margin-left: 20px; margin-left: 20px;
} }
Expand All @@ -105,4 +113,14 @@ ul li.toc a {
ul li.toc_section a { ul li.toc_section a {
font-weight: bold; font-weight: bold;
border-bottom: 1px solid #5B618F; 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.