Skip to content

Commit b075c2d

Browse files
committed
Display htmlized pages much more like tools.ietf.org. Commit ready for merge.
- Legacy-Id: 18869
2 parents 160030c + 1781f53 commit b075c2d

File tree

7 files changed

+341
-83
lines changed

7 files changed

+341
-83
lines changed

ietf/doc/tests.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ def test_document_draft(self):
677677
q = PyQuery(r.content)
678678
self.assertEqual(len(q('.rfcmarkup pre')), 4)
679679
self.assertEqual(len(q('.rfcmarkup span.h1')), 2)
680-
self.assertEqual(len(q('.rfcmarkup a[href]')), 31)
680+
self.assertEqual(len(q('.rfcmarkup a[href]')), 41)
681681

682682
r = self.client.get(urlreverse("ietf.doc.views_doc.document_html", kwargs=dict(name=draft.name, rev=draft.rev)))
683683
self.assertEqual(r.status_code, 200)

ietf/doc/utils.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,81 @@ def join_justified(left, right, width=72):
934934
break
935935
return lines
936936

937+
def build_file_urls(doc):
938+
if doc.get_state_slug() == "rfc":
939+
name = doc.canonical_name()
940+
base_path = os.path.join(settings.RFC_PATH, name + ".")
941+
possible_types = settings.RFC_FILE_TYPES
942+
found_types = [t for t in possible_types if os.path.exists(base_path + t)]
943+
944+
base = "https://www.rfc-editor.org/rfc/"
945+
946+
file_urls = []
947+
for t in found_types:
948+
label = "plain text" if t == "txt" else t
949+
file_urls.append((label, base + name + "." + t))
950+
951+
if "pdf" not in found_types and "txt" in found_types:
952+
file_urls.append(("pdf", base + "pdfrfc/" + name + ".txt.pdf"))
953+
954+
if "txt" in found_types:
955+
file_urls.append(("htmlized", settings.TOOLS_ID_HTML_URL + name))
956+
if doc.tags.filter(slug="verified-errata").exists():
957+
file_urls.append(("with errata", settings.RFC_EDITOR_INLINE_ERRATA_URL.format(rfc_number=doc.rfc_number())))
958+
file_urls.append(("bibtex", urlreverse('ietf.doc.views_doc.document_main',kwargs=dict(name=name))+"bibtex"))
959+
else:
960+
base_path = os.path.join(settings.INTERNET_DRAFT_PATH, doc.name + "-" + doc.rev + ".")
961+
possible_types = settings.IDSUBMIT_FILE_TYPES
962+
found_types = [t for t in possible_types if os.path.exists(base_path + t)]
963+
base = settings.IETF_ID_ARCHIVE_URL
964+
file_urls = []
965+
for t in found_types:
966+
label = "plain text" if t == "txt" else t
967+
file_urls.append((label, base + doc.name + "-" + doc.rev + "." + t))
968+
969+
if "pdf" not in found_types:
970+
file_urls.append(("pdf", settings.TOOLS_ID_PDF_URL + doc.name + "-" + doc.rev + ".pdf"))
971+
file_urls.append(("htmlized (tools)", settings.TOOLS_ID_HTML_URL + doc.name + "-" + doc.rev))
972+
file_urls.append(("htmlized", urlreverse('ietf.doc.views_doc.document_html', kwargs=dict(name=doc.name, rev=doc.rev))))
973+
file_urls.append(("bibtex", urlreverse('ietf.doc.views_doc.document_main',kwargs=dict(name=doc.name,rev=doc.rev))+"bibtex"))
974+
975+
return file_urls, found_types
976+
977+
def build_doc_supermeta_block(doc):
978+
items = []
979+
items.append(f'[<a href="{ settings.IDTRACKER_BASE_URL }" title="Document search and retrieval page">Search</a>]')
980+
981+
file_urls, found_types = build_file_urls(doc)
982+
file_urls = [('txt',url) if label=='plain text' else (label,url) for label,url in file_urls]
983+
984+
if file_urls:
985+
file_labels = {
986+
'txt' : 'Plaintext version of this document',
987+
'xml' : 'XML source for this document',
988+
'pdf' : 'PDF version of this document',
989+
'html' : 'HTML version of this document, from XML2RFC',
990+
'bibtex' : 'BibTex entry for this document',
991+
}
992+
parts=[]
993+
for label,url in file_urls:
994+
if 'htmlized' not in label:
995+
file_label=file_labels.get(label,'')
996+
title_attribute = f' title="{file_label}"' if file_label else ''
997+
partstring = f'<a href="{url}"{title_attribute}>{label}</a>'
998+
parts.append(partstring)
999+
items.append('[' + '|'.join(parts) + ']')
1000+
1001+
items.append(f'[<a href="{ urlreverse("ietf.doc.views_doc.document_main",kwargs=dict(name=doc.canonical_name())) }" title="Datatracker information for this document">Tracker</a>]')
1002+
if doc.group.acronym != 'none':
1003+
items.append(f'[<a href="{urlreverse("ietf.group.views.group_home",kwargs=dict(acronym=doc.group.acronym))}" title="The working group handling this document">WG</a>]')
1004+
items.append(f'[<a href="mailto:{doc.name}@ietf.org?subject={doc.name}" title="Send email to the document authors">Email</a>]')
1005+
if doc.rev != "00":
1006+
items.append(f'[<a href="{settings.RFCDIFF_BASE_URL}?difftype=--hwdiff&url2={doc.name}-{doc.rev}.txt" title="Inline diff (wdiff)">Diff1</a>]')
1007+
items.append(f'[<a href="{settings.RFCDIFF_BASE_URL}?url2={doc.name}-{doc.rev}.txt" title="Side-by-side diff">Diff2</a>]')
1008+
items.append(f'[<a href="{settings.IDNITS_BASE_URL}?url={settings.IETF_ID_ARCHIVE_URL}{doc.name}-{doc.rev}.txt" title="Run an idnits check of this document">Nits</a>]')
1009+
1010+
return ' '.join(items)
1011+
9371012
def build_doc_meta_block(doc, path):
9381013
def add_markup(path, doc, lines):
9391014
is_hst = doc.is_dochistory()

ietf/doc/views_doc.py

Lines changed: 26 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
needed_ballot_positions, nice_consensus, prettify_std_name, update_telechat, has_same_ballot,
6161
get_initial_notify, make_notify_changed_event, make_rev_history, default_consensus,
6262
add_events_message_info, get_unicode_document_content, build_doc_meta_block,
63-
augment_docs_and_user_with_user_info, irsg_needed_ballot_positions, add_action_holder_change_event )
63+
augment_docs_and_user_with_user_info, irsg_needed_ballot_positions, add_action_holder_change_event, build_doc_supermeta_block, build_file_urls )
6464
from ietf.group.models import Role, Group
6565
from ietf.group.utils import can_manage_group_type, can_manage_materials, group_features_role_filter
6666
from ietf.ietfauth.utils import ( has_role, is_authorized_in_doc_stream, user_is_person,
@@ -210,69 +210,21 @@ def document_main(request, name, rev=None):
210210

211211
latest_revision = None
212212

213-
if doc.get_state_slug() == "rfc":
214-
# content
215-
content = doc.text_or_error() # pyflakes:ignore
216-
content = markup_txt.markup(maybe_split(content, split=split_content))
217-
218-
# file types
219-
base_path = os.path.join(settings.RFC_PATH, name + ".")
220-
possible_types = settings.RFC_FILE_TYPES
221-
found_types = [t for t in possible_types if os.path.exists(base_path + t)]
222-
223-
base = "https://www.rfc-editor.org/rfc/"
213+
file_urls, found_types = build_file_urls(doc)
224214

225-
file_urls = []
226-
for t in found_types:
227-
label = "plain text" if t == "txt" else t
228-
file_urls.append((label, base + name + "." + t))
229-
230-
if "pdf" not in found_types and "txt" in found_types:
231-
file_urls.append(("pdf", base + "pdfrfc/" + name + ".txt.pdf"))
232-
233-
if "txt" in found_types:
234-
file_urls.append(("htmlized", settings.TOOLS_ID_HTML_URL + name))
235-
if doc.tags.filter(slug="verified-errata").exists():
236-
file_urls.append(("with errata", settings.RFC_EDITOR_INLINE_ERRATA_URL.format(rfc_number=rfc_number)))
215+
content = doc.text_or_error() # pyflakes:ignore
216+
content = markup_txt.markup(maybe_split(content, split=split_content))
237217

218+
if doc.get_state_slug() == "rfc":
238219
if not found_types:
239220
content = "This RFC is not currently available online."
240221
split_content = False
241222
elif "txt" not in found_types:
242223
content = "This RFC is not available in plain text format."
243224
split_content = False
244225
else:
245-
content = doc.text_or_error() # pyflakes:ignore
246-
content = markup_txt.markup(maybe_split(content, split=split_content))
247-
248-
# file types
249-
base_path = os.path.join(settings.INTERNET_DRAFT_PATH, doc.name + "-" + doc.rev + ".")
250-
possible_types = settings.IDSUBMIT_FILE_TYPES
251-
found_types = [t for t in possible_types if os.path.exists(base_path + t)]
252-
253-
# if not snapshot and doc.get_state_slug() == "active":
254-
# base = settings.IETF_ID_URL
255-
# else:
256-
# base = settings.IETF_ID_ARCHIVE_URL
257-
base = settings.IETF_ID_ARCHIVE_URL
258-
259-
file_urls = []
260-
for t in found_types:
261-
label = "plain text" if t == "txt" else t
262-
file_urls.append((label, base + doc.name + "-" + doc.rev + "." + t))
263-
264-
if "pdf" not in found_types:
265-
file_urls.append(("pdf", settings.TOOLS_ID_PDF_URL + doc.name + "-" + doc.rev + ".pdf"))
266-
#file_urls.append(("htmlized", settings.TOOLS_ID_HTML_URL + doc.name + "-" + doc.rev))
267-
file_urls.append(("htmlized (tools)", settings.TOOLS_ID_HTML_URL + doc.name + "-" + doc.rev))
268-
file_urls.append(("htmlized", urlreverse('ietf.doc.views_doc.document_html', kwargs=dict(name=doc.name, rev=doc.rev))))
269-
270-
# latest revision
271226
latest_revision = doc.latest_event(NewRevisionDocEvent, type="new_revision")
272227

273-
# bibtex
274-
file_urls.append(("bibtex", "bibtex"))
275-
276228
# ballot
277229
iesg_ballot_summary = None
278230
irsg_ballot_summary = None
@@ -707,7 +659,6 @@ def document_html(request, name, rev=None):
707659
if not os.path.exists(doc.get_file_name()):
708660
raise Http404("File not found: %s" % doc.get_file_name())
709661

710-
top = render_document_top(request, doc, "status", name)
711662
if not rev and not name.startswith('rfc'):
712663
rev = doc.rev
713664
if rev:
@@ -717,9 +668,29 @@ def document_html(request, name, rev=None):
717668
else:
718669
doc = doc.fake_history_obj(rev)
719670
if doc.type_id in ['draft',]:
671+
doc.supermeta = build_doc_supermeta_block(doc)
720672
doc.meta = build_doc_meta_block(doc, settings.HTMLIZER_URL_PREFIX)
721673

722-
return render(request, "doc/document_html.html", {"doc":doc, "top":top, "navbar_mode":"navbar-static-top", })
674+
doccolor = 'bgwhite' # Unknown
675+
if doc.type_id=='draft':
676+
if doc.is_rfc():
677+
if doc.related_that('obs'):
678+
doccolor = 'bgbrown'
679+
else:
680+
doccolor = {
681+
'ps' : 'bgblue',
682+
'exp' : 'bgyellow',
683+
'inf' : 'bgorange',
684+
'ds' : 'bgcyan',
685+
'hist' : 'bggrey',
686+
'std' : 'bggreen',
687+
'bcp' : 'bgmagenta',
688+
'unkn' : 'bgwhite',
689+
}.get(doc.std_level_id, 'bgwhite')
690+
else:
691+
doccolor = 'bgred' # Draft
692+
693+
return render(request, "doc/document_html.html", {"doc":doc, "doccolor":doccolor })
723694

724695
def check_doc_email_aliases():
725696
pattern = re.compile(r'^expand-(.*?)(\..*?)?@.*? +(.*)$')

ietf/settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,7 @@ def skip_unreadable_post(record):
549549
# no slash at end
550550
IDTRACKER_BASE_URL = "https://datatracker.ietf.org"
551551
RFCDIFF_BASE_URL = "https://www.ietf.org/rfcdiff"
552+
IDNITS_BASE_URL = "https://www.ietf.org/tools/idnits"
552553

553554
# The name of the method to use to invoke the test suite
554555
TEST_RUNNER = 'ietf.utils.test_runner.IetfTestRunner'

ietf/templates/doc/document_draft.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@
675675
<a class="btn btn-default btn-xs" href="{% url "ietf.ipr.views.search" %}?submit=draft&amp;id={{ doc.name }}" rel="nofollow"><span class="fa fa-bolt"></span> IPR {% if doc.related_ipr %} <span class="badge">{{doc.related_ipr|length}}</span>{% endif %}</a>
676676
<a class="btn btn-default btn-xs" href="{% url 'ietf.doc.views_doc.document_references' doc.canonical_name %}" rel="nofollow"><span class="fa fa-long-arrow-left"></span> References</a>
677677
<a class="btn btn-default btn-xs" href="{% url 'ietf.doc.views_doc.document_referenced_by' doc.canonical_name %}" rel="nofollow"><span class="fa fa-long-arrow-right"></span> Referenced by</a>
678-
<a class="btn btn-default btn-xs" href="https://www.ietf.org/tools/idnits?url=https://www.ietf.org/archive/id/{{ doc.filename_with_rev }}" rel="nofollow" target="_blank"><span class="fa fa-exclamation"></span> Nits</a>
678+
<a class="btn btn-default btn-xs" href="{{settings.IDNITS_BASE_URL}}?url=https://www.ietf.org/archive/id/{{ doc.filename_with_rev }}" rel="nofollow" target="_blank"><span class="fa fa-exclamation"></span> Nits</a>
679679
<div class="dropdown inline">
680680
<button class="btn btn-default btn-xs dropdown-toggle" type="button" id="ddSearchMenu" data-toggle="dropdown" aria-expanded="true">
681681
<span class="fa fa-search"></span> Search lists <span class="caret"></span>
Lines changed: 76 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{% extends "base.html" %}
1+
{% extends "doc/htmlized_base.html" %}
22
{# Copyright The IETF Trust 2016, All Rights Reserved #}
33
{% load origin %}
44
{% load static %}
@@ -12,7 +12,20 @@
1212
{% endblock %}
1313

1414
{% block morecss %}
15-
.inline { display: inline; }
15+
16+
.bgwhite { background-color: white; }
17+
.bgred { background-color: #F44; }
18+
.bggrey { background-color: #666; }
19+
.bgbrown { background-color: #840; }
20+
.bgorange { background-color: #FA0; }
21+
.bgyellow { background-color: #EE0; }
22+
.bgmagenta{ background-color: #F4F; }
23+
.bgblue { background-color: #66F; }
24+
.bgcyan { background-color: #4DD; }
25+
.bggreen { background-color: #4F4; }
26+
27+
.draftcontent { margin-top:0px !important;}
28+
1629
{% endblock %}
1730

1831
{% block title %}
@@ -23,43 +36,80 @@
2336
{% endif %}
2437
{% endblock %}
2538

26-
{% block bodyAttrs %}style="padding-top: 0;"{% endblock %}
39+
{% block bodyAttrs %}onload="addHeaderTags()" style="padding-top: 0;"{% endblock %}
2740

2841
{% block content %}
2942
{% origin %}
30-
<div class="hidden-print">
31-
{{ top | safe }}
32-
</div>
43+
44+
<div class="rfcmarkup">
45+
<div class="noprint" style="height: 6px;">
46+
<div onmouseover="this.style.cursor='pointer';"
47+
onclick="showElem('legend');"
48+
onmouseout="hideElem('legend')"
49+
style="height: 6px; min-height: 6px; width: 96ex; position: absolute; margin-top:0; "
50+
class="meta-info {{doccolor}}"
51+
title="Click for colour legend." >&nbsp;</div>
52+
<div id="legend"
53+
class="meta-info noprint pre legend"
54+
style="position:absolute; top: 4px; left: 4ex; visibility:hidden; background-color: white; padding: 4px 9px 5px 7px; border: solid #345 1px; "
55+
onmouseover="showElem('legend');"
56+
onmouseout="hideElem('legend');">
57+
</div>
58+
</div>
3359

34-
{# {% include "doc/revisions_list.html" %} #}
35-
<div class="col-md-2"></div>
36-
<div class="col-md-8 rfcmarkup">
3760
{% if doc.meta %}
38-
<div class="hidden-print">
39-
<pre class="meta-info">{{ doc.meta|safe }}</pre>
40-
</div>
41-
{% endif %}
61+
<div class="noprint">
62+
<pre class="pre meta-info">{{ doc.supermeta|safe }}
4263

43-
{% comment %}
44-
{% if doc.is_dochistory %}
45-
{% if doc.rev != doc.doc.rev %}
46-
<pre class="meta-info alert-warning text-center">A newer version of the document below exists</pre>
47-
{% elif doc.doc.is_rfc %}
48-
<pre class="meta-info alert-info text-center">The draft below has been published as <a href="{% url 'ietf.doc.views_doc.document_html' name=doc.doc.canonical_name %}">RFC {{doc.doc.rfc_number}}</a></pre>
49-
{% endif %}
64+
{{ doc.meta|safe }}</pre>
65+
</div>
5066
{% endif %}
51-
{% endcomment %}
5267

53-
<div>
68+
<div class="draftcontent">
5469
{{ doc.htmlized|default:"Generation of htmlized text failed"|safe }}
5570
</div>
5671

5772
</div>
58-
<div class="col-md-1"></div>
59-
<div class="col-md-1"></div>
6073

6174
{% endblock %}
6275

63-
{% block footer %}
64-
<div></div>
76+
{% block js %}
77+
<script type="text/javascript"><!--
78+
function addHeaderTags() {
79+
var spans = document.getElementsByTagName("span");
80+
for (var i=0; i < spans.length; i++) {
81+
var elem = spans[i];
82+
if (elem) {
83+
var level = elem.getAttribute("class");
84+
if (level == "h1" || level == "h2" || level == "h3" || level == "h4" || level == "h5" || level == "h6") {
85+
elem.innerHTML = "<"+level+">"+elem.innerHTML+"</"+level+">";
86+
}
87+
}
88+
}
89+
}
90+
var legend_html = "Colour legend:<br /> \
91+
<table> \
92+
<tr><td>Unknown:</td> <td><span class='cplate bgwhite'>&nbsp;&nbsp;&nbsp;&nbsp;</span></td></tr> \
93+
<tr><td>Draft:</td> <td><span class='cplate bgred'>&nbsp;&nbsp;&nbsp;&nbsp;</span></td></tr> \
94+
<tr><td>Informational:</td> <td><span class='cplate bgorange'>&nbsp;&nbsp;&nbsp;&nbsp;</span></td></tr> \
95+
<tr><td>Experimental:</td> <td><span class='cplate bgyellow'>&nbsp;&nbsp;&nbsp;&nbsp;</span></td></tr> \
96+
<tr><td>Best Common Practice:</td> <td><span class='cplate bgmagenta'>&nbsp;&nbsp;&nbsp;&nbsp;</span></td></tr> \
97+
<tr><td>Proposed Standard:</td> <td><span class='cplate bgblue'>&nbsp;&nbsp;&nbsp;&nbsp;</span></td></tr> \
98+
<tr><td>Draft Standard (old designation):</td> <td><span class='cplate bgcyan'>&nbsp;&nbsp;&nbsp;&nbsp;</span></td></tr> \
99+
<tr><td>Internet Standard:</td> <td><span class='cplate bggreen'>&nbsp;&nbsp;&nbsp;&nbsp;</span></td></tr> \
100+
<tr><td>Historic:</td> <td><span class='cplate bggrey'>&nbsp;&nbsp;&nbsp;&nbsp;</span></td></tr> \
101+
<tr><td>Obsolete:</td> <td><span class='cplate bgbrown'>&nbsp;&nbsp;&nbsp;&nbsp;</span></td></tr> \
102+
</table>";
103+
function showElem(id) {
104+
var elem = document.getElementById(id);
105+
elem.innerHTML = eval(id+"_html");
106+
elem.style.visibility='visible';
107+
}
108+
function hideElem(id) {
109+
var elem = document.getElementById(id);
110+
elem.style.visibility='hidden';
111+
elem.innerHTML = "";
112+
}
113+
// -->
114+
</script>
65115
{% endblock %}

0 commit comments

Comments
 (0)