Skip to content

Instantly share code, notes, and snippets.

@cmpute
Last active December 17, 2022 05:08
Show Gist options
  • Save cmpute/0f1ec6d7c3efb0f1eebeead01b4cfcb9 to your computer and use it in GitHub Desktop.
Save cmpute/0f1ec6d7c3efb0f1eebeead01b4cfcb9 to your computer and use it in GitHub Desktop.
Proposal for rustdoc index

Index Design of the Rustdoc

  • This index section is only available for structs yet.
  • The whole index should be put under the type documentation of a struct in the documentation body, and collapsed by default.
  • Auto and blanket trait implementations are not separated from normal traits.
  • The pub modifier is omitted by default, maybe we can display it when --private-items flag is enabled.
  • Trait bounds for generic parameters are omitted
  • The type for const generic parameters are omitted.
  • Each table is not necessarily rendered as tables in HTML, they can be rendered like the summary of a module, and the headers are not necessary as well.
  • We might also add a button on the top right (beside the [+] button) for jumping to the index, in case the type documentation is too long.
  • The description column could be hidden for narrow display (such as mobile)

Questions to be solved:

  • How to combine multiple implementations for a generic trait in the index
  • Shall we separate From<Self> implemented for type Other from From<Other> implemented for Self?

Examples

Index of std::vec::Vec (Style 1)

Methods on self

Modifier Name Output Description
fn into_boxed_slice(Self) -> Box<[T], A> Converts the vector into Box<[T]>.
fn into_flattened(Self) -> Vec<T, A> Takes a Vec<[T; N]> and flattens it into a Vec.
fn into_raw_parts(Self) -> (*mut T, usize, usize) Decomposes a Vec into its raw components.
fn into_raw_parts_with_alloc(self) -> (*mut T, usize, usize, A) Decomposes a Vec into its raw components.
fn leak<'a>(Self) -> &'a mut [T] Consumes and leaks the Vec, returning a mutable reference to the contents, &'a mut [T].
.. .. .. ..

Methods on &self

Modifier Name Output Description
fn allocator(&Self) -> &A Returns a reference to the underlying allocator.
fn as_ptr(&Self) -> *const T Returns a raw pointer to the vector’s buffer, or a dangling raw pointer valid for zero sized reads if the vector didn’t allocate.
fn as_slice(&Self) -> &[T] Extracts a slice containing the entire vector.
fn capacity(&Self) -> usize Returns the number of elements the vector can hold without reallocating.
fn is_empty(&Self) -> bool Returns true if the vector contains no elements.
fn len(&Self) -> usize Returns the number of elements in the vector, also referred to as its ‘length’.
.. .. .. ..

Methods on &mut self

Modifier Name Output Description
fn as_mut_ptr(&mut Self) -> *mut T Returns an unsafe mutable pointer to the vector’s buffer, or a dangling raw pointer valid for zero sized reads if the vector didn’t allocate.
fn reserve(&mut Self, usize) Reserves capacity for at least additional more elements to be inserted in the given Vec.
fn reserve_exact(&mut Self, usize) Reserves the minimum capacity for at least additional more elements to be inserted in the given Vec.
unsafe fn set_len(&mut Self, usize) Forces the length of the vector to new_len.
fn try_reserve(&mut Self, usize) -> Result<(), TryReserveError> Tries to reserve capacity for at least additional more elements to be inserted in the given Vec.
fn try_reserve_exact(&mut Self, usize) -> Result<(), TryReserveError> Tries to reserve the minimum capacity for at least additional elements to be inserted in the given Vec.
.. .. .. ..

Static Methods

Modifier Name Output Description
unsafe fn from_raw_parts(*mut T, usize, usize) -> Vec<T, Global> Creates a Vec directly from the raw components of another vector.
unsafe fn from_raw_parts_in(*mut T, usize, usize, A) -> Vec<T, A> Creates a Vec<T, A> directly from the raw components of another vector.
const fn new() -> Vec<T, Global> Constructs a new, empty Vec.
const fn new_in(A) -> Vec<T, A> Constructs a new, empty Vec<T, A>.
fn with_capacity(usize) -> Vec<T, Global> Constructs a new, empty Vec with at least the specified capacity.
fn with_capacity_in(usize, A) -> Vec<T, A> Constructs a new, empty Vec<T, A> with at least the specified capacity with the provided allocator.
.. .. .. ..

Methods from Deref<Target=[T]>

Modifier Name Output Description
unsafe fn align_to(&Self) -> (&[T], &[U], &[T]) Transmute the slice to a slice of another type, ensuring alignment of the types is maintained.
unsafe fn align_to_mut(&mut Self) -> (&mut [T], &mut [U], &mut [T]) Transmute the slice to a slice of another type, ensuring alignment of the types is maintained.
fn as_simd(&Self) -> (&[T], &[Simd<T, LANES>], &[T]) Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.
fn as_simd_mut(&mut Self) -> (&mut [T], &mut [U], &mut [T]) Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.
.. .. .. ..

Generic Trait Implementations

  • AsMut: AsMut<[T]>, AsMut<Vec<T, A>>
  • AsRef: AsRef<[T]>, AsRef<Vec<T, A>>
  • Borrow: Borrow<[T]>
  • BorrowMut: BorrowMut<[T]>
  • Extend: Extend<&'a T>
  • ..

Methods from Traits

Modifier Trait Name Output Description
fn AsMut:: as_mut(&Self) -> &mut T Converts this type into a mutable reference of the (usually inferred) input type.
fn AsRef:: as_ref(&Self) -> &T Converts this type into a shared reference of the (usually inferred) input type.
fn Borrow:: borrow(&Self) -> &T Immutably borrows from an owned value.
fn BorrowMut:: borrow_mut(&mut Self) -> &mut T Mutably borrows from an owned value.
fn Clone:: clone(&Self) -> Vec<T, A> Returns a copy of the value.
fn Clone:: clone_from(&mut Self, &Vec<T, A>) Performs copy-assignment from source.
fn Debug:: fmt(&Self, &mut Formatter<'_>) -> Result<(), Error> Formats the value using the given formatter.
fn Deref:: deref(&Self) -> &[T] Dereferences the value.
.. .. .. .. ..
Index of std::vec::Vec (Style 2)

Methods on self

Modifier Name Description
fn into_boxed_slice(Self) -> Box<[T], A> Converts the vector into Box<[T]>.
fn into_flattened(Self) -> Vec<T, A> Takes a Vec<[T; N]> and flattens it into a Vec.
fn into_raw_parts(Self) -> (*mut T, usize, usize) Decomposes a Vec into its raw components.
fn into_raw_parts_with_alloc(self) -> (*mut T, usize, usize, A) Decomposes a Vec into its raw components.
fn leak<'a>(Self) -> &'a mut [T] Consumes and leaks the Vec, returning a mutable reference to the contents, &'a mut [T].
.. .. ..

Methods on &self

Modifier Name Description
fn allocator(&Self) -> &A Returns a reference to the underlying allocator.
fn as_ptr(&Self) -> *const T Returns a raw pointer to the vector’s buffer, or a dangling raw pointer valid for zero sized reads if the vector didn’t allocate.
fn as_slice(&Self) -> &[T] Extracts a slice containing the entire vector.
fn capacity(&Self) -> usize Returns the number of elements the vector can hold without reallocating.
fn is_empty(&Self) -> bool Returns true if the vector contains no elements.
fn len(&Self) -> usize Returns the number of elements in the vector, also referred to as its ‘length’.
.. .. ..

Methods on &mut self

Modifier Name Description
fn as_mut_ptr(&mut Self) -> *mut T Returns an unsafe mutable pointer to the vector’s buffer, or a dangling raw pointer valid for zero sized reads if the vector didn’t allocate.
fn reserve(&mut Self, usize) Reserves capacity for at least additional more elements to be inserted in the given Vec.
fn reserve_exact(&mut Self, usize) Reserves the minimum capacity for at least additional more elements to be inserted in the given Vec.
unsafe fn set_len(&mut Self, new_len: usize) Forces the length of the vector to new_len.
fn try_reserve(&mut Self, usize) -> Result<(), TryReserveError> Tries to reserve capacity for at least additional more elements to be inserted in the given Vec.
fn try_reserve_exact(&mut Self, usize) -> Result<(), TryReserveError> Tries to reserve the minimum capacity for at least additional elements to be inserted in the given Vec.
.. .. ..

Static Methods

Modifier Name Description
unsafe fn from_raw_parts(*mut T, usize, usize) -> Vec<T, Global> Creates a Vec directly from the raw components of another vector.
unsafe fn from_raw_parts_in(*mut T, usize, usize, A) -> Vec<T, A> Creates a Vec<T, A> directly from the raw components of another vector.
const fn new() -> Vec<T, Global> Constructs a new, empty Vec.
const fn new_in(A) -> Vec<T, A> Constructs a new, empty Vec<T, A>.
fn with_capacity(usize) -> Vec<T, Global> Constructs a new, empty Vec with at least the specified capacity.
fn with_capacity_in(usize, A) -> Vec<T, A> Constructs a new, empty Vec<T, A> with at least the specified capacity with the provided allocator.
.. .. ..

Methods from Deref<Target=[T]>

Modifier Name Description
unsafe fn align_to(&Self) -> (&[T], &[U], &[T]) Transmute the slice to a slice of another type, ensuring alignment of the types is maintained.
unsafe fn align_to_mut(&mut Self) -> (&mut [T], &mut [U], &mut [T]) Transmute the slice to a slice of another type, ensuring alignment of the types is maintained.
fn as_simd(&Self) -> (&[T], &[Simd<T, LANES>], &[T]) Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.
fn as_simd_mut(&mut Self) -> (&mut [T], &mut [U], &mut [T]) Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.
.. .. ..

Generic Trait Implementations

  • AsMut: AsMut<[T]>, AsMut<Vec<T, A>>
  • AsRef: AsRef<[T]>, AsRef<Vec<T, A>>
  • Borrow: Borrow<[T]>
  • BorrowMut: BorrowMut<[T]>
  • Extend: Extend<&'a T>
  • ..

Methods from Traits

Modifier Trait Name Description
fn AsMut:: as_mut(&Self) -> &mut T Converts this type into a mutable reference of the (usually inferred) input type.
fn AsRef:: as_ref(&Self) -> &T Converts this type into a shared reference of the (usually inferred) input type.
fn Borrow:: borrow(&Self) -> &T Immutably borrows from an owned value.
fn BorrowMut:: borrow_mut(&mut Self) -> &mut T Mutably borrows from an owned value.
fn Clone:: clone(&Self) -> Vec<T, A> Returns a copy of the value.
fn Clone:: clone_from(&mut Self, &Vec<T, A>) Performs copy-assignment from source.
fn Debug:: fmt(&Self, &mut Formatter<'_>) -> Result<(), Error> Formats the value using the given formatter.
fn Deref:: deref(&Self) -> &[T] Dereferences the value.
.. .. .. ..
Index of std::vec::Vec (Style 3)

Subscript for methods: A - async, U - unsafe, C - const

Methods on self

Name Description
into_boxed_slice(Self) -> Box<[T], A> Converts the vector into Box<[T]>.
into_flattened(Self) -> Vec<T, A> Takes a Vec<[T; N]> and flattens it into a Vec.
into_raw_parts(Self) -> (*mut T, usize, usize) Decomposes a Vec into its raw components.
into_raw_parts_with_alloc(self) -> (*mut T, usize, usize, A) Decomposes a Vec into its raw components.
leak<'a>(Self) -> &'a mut [T] Consumes and leaks the Vec, returning a mutable reference to the contents, &'a mut [T].
.. ..

Methods on &self

Name Description
allocator(&Self) -> &A Returns a reference to the underlying allocator.
as_ptr(&Self) -> *const T Returns a raw pointer to the vector’s buffer, or a dangling raw pointer valid for zero sized reads if the vector didn’t allocate.
as_slice(&Self) -> &[T] Extracts a slice containing the entire vector.
capacity(&Self) -> usize Returns the number of elements the vector can hold without reallocating.
is_empty(&Self) -> bool Returns true if the vector contains no elements.
len(&Self) -> usize Returns the number of elements in the vector, also referred to as its ‘length’.
.. ..

Methods on &mut self

Name Description
as_mut_ptr(&mut Self) -> *mut T Returns an unsafe mutable pointer to the vector’s buffer, or a dangling raw pointer valid for zero sized reads if the vector didn’t allocate.
reserve(&mut Self, ..) Reserves capacity for at least additional more elements to be inserted in the given Vec.
reserve_exact(&mut Self, ..) Reserves the minimum capacity for at least additional more elements to be inserted in the given Vec.
Uset_len(&mut Self, ..) Forces the length of the vector to new_len.
try_reserve(&mut Self, ..) -> Result<(), TryReserveError> Tries to reserve capacity for at least additional more elements to be inserted in the given Vec.
try_reserve_exact(&mut Self, ..) -> Result<(), TryReserveError> Tries to reserve the minimum capacity for at least additional elements to be inserted in the given Vec.
.. ..

Static Methods

Name Description
Ufrom_raw_parts(..) -> Vec<T, Global> Creates a Vec directly from the raw components of another vector.
Ufrom_raw_parts_in(..) -> Vec<T, A> Creates a Vec<T, A> directly from the raw components of another vector.
Cnew() -> Vec<T, Global> Constructs a new, empty Vec.
Cnew_in(..) -> Vec<T, A> Constructs a new, empty Vec<T, A>.
with_capacity(..) -> Vec<T, Global> Constructs a new, empty Vec with at least the specified capacity.
with_capacity_in(..) -> Vec<T, A> Constructs a new, empty Vec<T, A> with at least the specified capacity with the provided allocator.
.. ..

Methods from Deref<Target=[T]>

Name Description
Ualign_to(&Self) -> (&[T], &[U], &[T]) Transmute the slice to a slice of another type, ensuring alignment of the types is maintained.
Ualign_to_mut(&mut Self) -> (&mut [T], &mut [U], &mut [T]) Transmute the slice to a slice of another type, ensuring alignment of the types is maintained.
as_simd(&Self) -> (&[T], &[Simd<T, LANES>], &[T]) Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.
as_simd_mut(&mut Self) -> (&mut [T], &mut [U], &mut [T]) Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.
.. ..

Methods from Traits

Trait Name Description
AsMut:: as_mut(&Self) -> &mut [T] Converts this type into a mutable reference of the (usually inferred) input type.
AsMut:: as_mut(&Self) -> &mut Vec<T, A> Converts this type into a mutable reference of the (usually inferred) input type.
AsRef:: as_ref(&Self) -> &[T] Converts this type into a shared reference of the (usually inferred) input type.
AsRef:: as_ref(&Self) -> &Vec<T, A> Converts this type into a shared reference of the (usually inferred) input type.
Borrow:: borrow(&Self) -> &[T] Immutably borrows from an owned value.
Borrow:: borrow(&Self) -> &Vec<T, A> Immutably borrows from an owned value.
BorrowMut:: borrow_mut(&mut Self) -> &mut [T] Mutably borrows from an owned value.
BorrowMut:: borrow_mut(&mut Self) -> &mut Vec<T, A> Mutably borrows from an owned value.
Clone:: clone(&Self) -> Vec<T, A> Returns a copy of the value.
Clone:: clone_from(&mut Self, ..) Performs copy-assignment from source.
Debug:: fmt(&Self, ..) -> Result<(), Error> Formats the value using the given formatter.
Deref:: deref(&Self) -> &[T] Dereferences the value.
.. .. ..
Index of std::vec::Vec (Style 4)

Subscript for methods: A - async, U - unsafe, C - const

Methods on self

Name Description
into_boxed_slice(Self) -> Box<[T], A> Converts the vector into Box<[T]>.
into_flattened(Self) -> Vec<T, A> Takes a Vec<[T; N]> and flattens it into a Vec.
into_raw_parts(Self) -> (*mut T, usize, usize) Decomposes a Vec into its raw components.
into_raw_parts_with_alloc(self) -> (*mut T, usize, usize, A) Decomposes a Vec into its raw components.
leak<'a>(Self) -> &'a mut [T] Consumes and leaks the Vec, returning a mutable reference to the contents, &'a mut [T].
.. ..

Methods on &self

Name Description
allocator(&Self) -> &A Returns a reference to the underlying allocator.
as_ptr(&Self) -> *const T Returns a raw pointer to the vector’s buffer, or a dangling raw pointer valid for zero sized reads if the vector didn’t allocate.
as_slice(&Self) -> &[T] Extracts a slice containing the entire vector.
capacity(&Self) -> usize Returns the number of elements the vector can hold without reallocating.
is_empty(&Self) -> bool Returns true if the vector contains no elements.
len(&Self) -> usize Returns the number of elements in the vector, also referred to as its ‘length’.
.. ..

Methods on &mut self

Name Description
as_mut_ptr(&mut Self) -> *mut T Returns an unsafe mutable pointer to the vector’s buffer, or a dangling raw pointer valid for zero sized reads if the vector didn’t allocate.
reserve(&mut Self, ..) Reserves capacity for at least additional more elements to be inserted in the given Vec.
reserve_exact(&mut Self, ..) Reserves the minimum capacity for at least additional more elements to be inserted in the given Vec.
Uset_len(&mut Self, ..) Forces the length of the vector to new_len.
try_reserve(&mut Self, ..) -> Result<(), TryReserveError> Tries to reserve capacity for at least additional more elements to be inserted in the given Vec.
try_reserve_exact(&mut Self, ..) -> Result<(), TryReserveError> Tries to reserve the minimum capacity for at least additional elements to be inserted in the given Vec.
.. ..

Static Methods

Name Description
Ufrom_raw_parts(..) -> Vec<T, Global> Creates a Vec directly from the raw components of another vector.
Ufrom_raw_parts_in(..) -> Vec<T, A> Creates a Vec<T, A> directly from the raw components of another vector.
Cnew() -> Vec<T, Global> Constructs a new, empty Vec.
Cnew_in(..) -> Vec<T, A> Constructs a new, empty Vec<T, A>.
with_capacity(..) -> Vec<T, Global> Constructs a new, empty Vec with at least the specified capacity.
with_capacity_in(..) -> Vec<T, A> Constructs a new, empty Vec<T, A> with at least the specified capacity with the provided allocator.
.. ..

Methods from Implemented Traits

Trait Names
AsMut as_mut
AsRef as_ref
Borrow borrow
BorrowMut borrow_mut
Clone clone clone_from
Debug fmt
Deref deref
.. ..

See the sidebar for the list of implementations for generic traits.

See this section for methods of Deref<Target=[T]>.

References

import sys
from pathlib import Path
from collections import defaultdict
import urllib
import lxml.html as html
import bisect
'''
This file converts the existing documented pages to the new style
Test targets:
- target/doc/dashu_ratio/struct.RBig.html
- target/doc/dashu_base/sign/enum.Sign.html
'''
def parse_trait_impls(list_node):
trait_infos = {}
for trait_item in list_node.findall("details"):
trait_name = trait_item.findall('.//a[@class="trait"]')[-1].text
trait_id = trait_item.find('./summary/section').get("id")
trait_infos[trait_id] = (trait_name, trait_item)
return trait_infos
def improve_sidebar(this_type, sidebar_node, trait_infos):
trait_section_ul = sidebar_node.find('.//h3/a[@href="#trait-implementations"]/..').getnext()
# scan the side bar trait impls
trait_list_infos = defaultdict(list)
for trait_item in trait_section_ul.iter('li'):
trait_link = trait_item.find('a')
trait_text: str = trait_link.text
trait_id: str = trait_link.get("href")
# collect by name
if trait_text.find('<') < 0:
trait_name = trait_text
else:
trait_name = trait_text[:trait_text.find('<')]
trait_list_infos[trait_name].append(trait_item)
# modify the text if the target implemented for is not this type
for_type = urllib.parse.unquote(trait_id[trait_id.find("-for-") + 5:])
if '<' in for_type:
for_type = for_type[:for_type.find('<')]
if for_type != this_type:
suffix = html.fromstring('<span style="color: #999;"> for %s</span>' % for_type)
trait_link.append(suffix)
# find impls with duplicate name
for trait_name, trait_items in trait_list_infos.items():
if len(trait_items) == 1:
continue
new_tree = html.fromstring('<details class="rustdoc-toggle sidebar-impl-toggle" style="margin: 4px 0;"><summary>%s (%d impls)</summary><ul class="sidebar-sublist" style="padding-left: 0"></ul></details>' % (trait_name, len(trait_items)))
new_list = new_tree.find('ul')
for item in trait_items:
item.drop_tree()
new_list.append(item)
rem_names = [item.find('a').text for item in trait_section_ul.iter('li')]
idx = bisect.bisect(rem_names, trait_name)
trait_section_ul.insert(idx, new_tree)
def create_summary(impls_node, traits_impls_node):
# TODO: parse output type (strip generic params, display (..) for tuple)
normal_members = defaultdict(list) # item_type -> [(id, name, doc, props)]
if impls_node:
# get nodes of all functions
fn_nodes = []
for impl_block in impls_node[0].findall('details'):
for fn_block in impl_block.find('div').findall('details'):
fn_nodes.append(fn_block)
# parse the info of the nodes
for item in fn_nodes:
item_props = set()
summary = item.find('summary')
item_id = summary.find('section').get('id')
if item_id.startswith("method"):
item_link = summary.find('.//a[@class="fn"]')
item_name = item_link.text
fn_signature = summary.text_content()
args = fn_signature[fn_signature.find('(') + 1:fn_signature.find(')')].strip()
multi_args = args.find(",") >= 0
if multi_args:
first_arg = args[:args.find(",")].strip()
else:
first_arg = args
if first_arg.startswith("self"):
item_type = "method_self"
elif first_arg.startswith("&self"):
item_type = "method_self_ref"
elif first_arg.startswith("&mut self"):
item_type = "method_self_mut"
else:
assert first_arg.find("self") < 0
item_type = "method_static"
if multi_args and item_type != "method_static":
item_props.add("multi_args")
if item_type == "method_static" and args:
item_props.add("multi_args")
mods = fn_signature[:fn_signature.find('(')]
if mods.find("const ") >= 0:
item_props.add("const")
if mods.find("async ") >= 0:
item_props.add("async")
elif item_id.startswith("associatedconstant"):
item_name = summary.find('.//a[@class="constant"]').text
item_type = "asso_constant"
else:
raise RuntimeError("Unrecognized item")
comment_block = item.find('div').find('p')
normal_members[item_type].append((item_name, item_id, comment_block, item_props))
trait_members = {} # trait_path -> (trait name, trait id, [list of fn nodes])
if traits_impls_node:
for impl_block in traits_impls_node[0].findall('details'):
header_block = impl_block.find('summary').findall('.//a[@class="trait"]')[-1]
trait_name = header_block.text
trait_path = header_block.get("title").lstrip("trait ")
trait_id = impl_block.find('summary/section').get('id')
if trait_path in trait_members:
continue
methods = []
for sub_block in impl_block.find('div'):
if sub_block.tag == "section":
item_link = sub_block.find('.//a[@class="fn"]')
item_id = sub_block.get('id')
elif sub_block.tag == "details":
item_link = sub_block.find('.//a[@class="fn"]')
item_id = sub_block.find('./summary/section').get('id')
if item_link is None:
continue
methods.append((item_link.text, item_id))
trait_members[trait_path] = (trait_name, trait_id, methods)
# render
header = '<h2 id="summary" class="small-section-header">Summary<a href="#summary" class="anchor"></a></h2>'
header = html.fromstring(header)
body = html.fromstring('<details class="rustdoc-toggle top-doc" open><summary><span>Expand Summary</span></summary></details>')
body.append(html.fromstring("Superscripts: <code>a</code> - async; <code>c</code> - const; <code>u</code> - unsafe"))
item_order = ["method_static", "asso_constant", "method_self", "method_self_ref", "method_self_mut"]
for item_type in item_order:
members = normal_members[item_type]
if len(members) == 0:
continue
members.sort()
if item_type == "method_static":
title = "Static Methods"
elif item_type == "asso_constant":
title = "Associated Constants"
elif item_type == "method_self":
title = "Methods with <code>self</code>"
elif item_type == "method_self_ref":
title = "Methods with <code>&self</code>"
elif item_type == "method_self_mut":
title = "Methods with <code>&mut self</code>"
else:
title = "Unknown"
body.append(html.fromstring('<h3 style="margin-top: 12; margin-bottom: 7">%s</h3>' % title))
list_body = html.fromstring('<div class="item-table"></div>')
for (name, id, comment, props) in members:
row = html.fromstring('<div class="item-row"></div>')
icons = ""
if "async" in props:
icons += "<code>a</code>"
if "const" in props:
icons += "<code>c</code>"
if "unsafe" in props:
icons += "<code>u</code>"
left = html.fromstring('<div class="item-left module-item"><a href="#%s" class="fn">%s</a><sup>%s</sup></div>' % (id, name, icons))
right = html.fromstring('<div class="item-right docblock-short"></div>')
right.append(comment)
row.append(left)
row.append(right)
list_body.append(row)
body.append(list_body)
if trait_members:
body.append(html.fromstring('<h3 style="margin-top: 12; margin-bottom: 7">Trait Methods</h3>'))
body.append(html.fromstring('<p>Sorted by full paths of the traits.</p>'))
list_body = html.fromstring('<div class="item-table"></div>')
# here the traits are sorted by module
sorted_names = list(trait_members.keys())
sorted_names.sort()
for name in sorted_names:
trait_name, trait_id, fn_list = trait_members[name]
row = html.fromstring('<div class="item-row"></div>')
left = html.fromstring('<div class="item-left module-item"><a href="#%s" class="fn">%s</a></div>' % (trait_id, name))
right_content = ""
prepend_comma = False
for fn_name, fn_id in fn_list:
if prepend_comma:
right_content += ', <a href="#%s">%s</a>' % (fn_id, fn_name)
else:
right_content += '<a href="#%s">%s</a>' % (fn_id, fn_name)
prepend_comma = True
right = html.fromstring('<div class="item-right docblock-short">%s</div>' % right_content)
row.append(left)
row.append(right)
list_body.append(row)
body.append(list_body)
return (header, body)
def improve(doc_path: Path, override = False):
# load
doc = html.fromstring(doc_path.read_text())
sidebar = doc.xpath('//div[@class="sidebar-elems"]')[0]
this_type = doc.xpath('//a[@href="#"]')[0].text
extra_style = """<style>
.sidebar details.sidebar-impl-toggle > summary {
cursor: pointer;
}
.sidebar details.sidebar-impl-toggle > summary:hover {
background-color: #444;
}
.sidebar details.sidebar-impl-toggle > summary::before {
background: none;
}
.sidebar details.sidebar-impl-toggle[open] > summary::before {
background: none;
}
.sidebar details.sidebar-impl-toggle[open] > summary {
background-color: #444;
}
details.sidebar-impl-toggle ul {
background-color: #444;
}
</style>"""
doc.xpath('//head')[0].append(html.fromstring(extra_style))
# add summary
impls = doc.xpath('//div[@id="implementations-list"]')
traits_impls = doc.xpath('//div[@id="trait-implementations-list"]')
header, body = create_summary(impls, traits_impls)
impls_header = doc.xpath('//section[@id="main-content"]/h2')[0]
impls_header.addprevious(header)
impls_header.addprevious(body)
doc.xpath('//div[@class="sidebar-elems"]/section')[0].insert(0,
html.fromstring('<div class="block"><h3 class="sidebar-title"><a href="#summary">Summary</a></h3></div>'))
# modify sidebar
if traits_impls:
trait_infos = parse_trait_impls(traits_impls[0])
improve_sidebar(this_type, sidebar, trait_infos)
# save
output = html.tostring(doc)
if override:
doc_path.write_bytes(output)
else:
doc_path.with_suffix(".edit.html").write_bytes(output)
if __name__ == "__main__":
doc_path = Path(sys.argv[1])
if doc_path.is_dir():
for page in doc_path.rglob('*.html'):
if page.name.startswith("struct") or page.name.startswith("enum") or page.name.startswith("primitive"):
try:
improve(page, True)
print("Processed", page.name)
except:
print("Failed", page.name)
continue
else:
improve(doc_path)
@cmpute
Copy link
Author

cmpute commented Dec 17, 2022

Some live examples: i64, std::vec::Vec, dashu_base::Sign, dashu_int::UBig

Some details to be finalized:

  1. Should we (partially) include the function signatures (like style 4). Maybe we can use tooltips to show the signature?
  2. How do we sort the traits, by name or by full path?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment