conflict fix

This commit is contained in:
iDutchy 2020-09-30 22:42:28 +00:00
commit f80b4c166c
21 changed files with 2215 additions and 379 deletions

142
docs/_static/codeblocks.css vendored Normal file
View File

@ -0,0 +1,142 @@
/* light theme: default */
.highlight .hll { background-color: #ffffcc }
.highlight { background: #f0f0f0; }
.highlight .c { color: #60a0b0; font-style: italic } /* Comment */
.highlight .err { border: 1px solid #FF0000 } /* Error */
.highlight .k { color: #007020; font-weight: bold } /* Keyword */
.highlight .o { color: #666666 } /* Operator */
.highlight .ch { color: #60a0b0; font-style: italic } /* Comment.Hashbang */
.highlight .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #007020 } /* Comment.Preproc */
.highlight .cpf { color: #60a0b0; font-style: italic } /* Comment.PreprocFile */
.highlight .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */
.highlight .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #A00000 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #FF0000 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #00A000 } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #0044DD } /* Generic.Traceback */
.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #007020 } /* Keyword.Pseudo */
.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #902000 } /* Keyword.Type */
.highlight .m { color: #40a070 } /* Literal.Number */
.highlight .s { color: #4070a0 } /* Literal.String */
.highlight .na { color: #4070a0 } /* Name.Attribute */
.highlight .nb { color: #007020 } /* Name.Builtin */
.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
.highlight .no { color: #60add5 } /* Name.Constant */
.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
.highlight .ne { color: #007020 } /* Name.Exception */
.highlight .nf { color: #06287e } /* Name.Function */
.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #bb60d5 } /* Name.Variable */
.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #40a070 } /* Literal.Number.Bin */
.highlight .mf { color: #40a070 } /* Literal.Number.Float */
.highlight .mh { color: #40a070 } /* Literal.Number.Hex */
.highlight .mi { color: #40a070 } /* Literal.Number.Integer */
.highlight .mo { color: #40a070 } /* Literal.Number.Oct */
.highlight .sa { color: #4070a0 } /* Literal.String.Affix */
.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
.highlight .sc { color: #4070a0 } /* Literal.String.Char */
.highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */
.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: #4070a0 } /* Literal.String.Double */
.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
.highlight .sx { color: #c65d09 } /* Literal.String.Other */
.highlight .sr { color: #235388 } /* Literal.String.Regex */
.highlight .s1 { color: #4070a0 } /* Literal.String.Single */
.highlight .ss { color: #517918 } /* Literal.String.Symbol */
.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #06287e } /* Name.Function.Magic */
.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
.highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */
.highlight .il { color: #40a070 } /* Literal.Number.Integer.Long */
/* dark theme: modified "native" */
:root[data-theme="dark"] .highlight pre { background-color: #2a2a2e }
:root[data-theme="dark"] .highlight .hll { background-color: #2a2a2e }
:root[data-theme="dark"] .highlight .c { color: #999999; font-style: italic } /* Comment */
:root[data-theme="dark"] .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
:root[data-theme="dark"] .highlight .g { color: #d0d0d0 } /* Generic */
:root[data-theme="dark"] .highlight .k { color: #6ab825; font-weight: bold } /* Keyword */
:root[data-theme="dark"] .highlight .l { color: #d0d0d0 } /* Literal */
:root[data-theme="dark"] .highlight .n { color: #d0d0d0 } /* Name */
:root[data-theme="dark"] .highlight .o { color: #d0d0d0 } /* Operator */
:root[data-theme="dark"] .highlight .x { color: #d0d0d0 } /* Other */
:root[data-theme="dark"] .highlight .p { color: #d0d0d0 } /* Punctuation */
:root[data-theme="dark"] .highlight .cm { color: #999999; font-style: italic } /* Comment.Multiline */
:root[data-theme="dark"] .highlight .cp { color: #cd2828; font-weight: bold } /* Comment.Preproc */
:root[data-theme="dark"] .highlight .c1 { color: #999999; font-style: italic } /* Comment.Single */
:root[data-theme="dark"] .highlight .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */
:root[data-theme="dark"] .highlight .gd { color: #d22323 } /* Generic.Deleted */
:root[data-theme="dark"] .highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */
:root[data-theme="dark"] .highlight .gr { color: #d22323 } /* Generic.Error */
:root[data-theme="dark"] .highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */
:root[data-theme="dark"] .highlight .gi { color: #589819 } /* Generic.Inserted */
:root[data-theme="dark"] .highlight .go { color: #cccccc } /* Generic.Output */
:root[data-theme="dark"] .highlight .gp { color: #aaaaaa } /* Generic.Prompt */
:root[data-theme="dark"] .highlight .gs { color: #d0d0d0; font-weight: bold } /* Generic.Strong */
:root[data-theme="dark"] .highlight .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */
:root[data-theme="dark"] .highlight .gt { color: #d22323 } /* Generic.Traceback */
:root[data-theme="dark"] .highlight .kc { color: #6ab825; font-weight: bold } /* Keyword.Constant */
:root[data-theme="dark"] .highlight .kd { color: #6ab825; font-weight: bold } /* Keyword.Declaration */
:root[data-theme="dark"] .highlight .kn { color: #6ab825; font-weight: bold } /* Keyword.Namespace */
:root[data-theme="dark"] .highlight .kp { color: #6ab825 } /* Keyword.Pseudo */
:root[data-theme="dark"] .highlight .kr { color: #6ab825; font-weight: bold } /* Keyword.Reserved */
:root[data-theme="dark"] .highlight .kt { color: #6ab825; font-weight: bold } /* Keyword.Type */
:root[data-theme="dark"] .highlight .ld { color: #d0d0d0 } /* Literal.Date */
:root[data-theme="dark"] .highlight .m { color: #7fb1d7 } /* Literal.Number */
:root[data-theme="dark"] .highlight .s { color: #ed9d13 } /* Literal.String */
:root[data-theme="dark"] .highlight .na { color: #bbbbbb; } /* Name.Attribute */
:root[data-theme="dark"] .highlight .nb { color: #29a5b3; } /* Name.Builtin */
:root[data-theme="dark"] .highlight .nc { color: #6494d8;} /* Name.Class */
:root[data-theme="dark"] .highlight .no { color: #40ffff; } /* Name.Constant */
:root[data-theme="dark"] .highlight .nd { color: #ffa500; } /* Name.Decorator */
:root[data-theme="dark"] .highlight .ni { color: #d0d0d0; } /* Name.Entity */
:root[data-theme="dark"] .highlight .ne { color: #bbbbbb; } /* Name.Exception */
:root[data-theme="dark"] .highlight .nf { color: #6494d8; } /* Name.Function */
:root[data-theme="dark"] .highlight .nl { color: #d0d0d0; } /* Name.Label */
:root[data-theme="dark"] .highlight .nn { color: #6494d8;} /* Name.Namespace */
:root[data-theme="dark"] .highlight .nx { color: #d0d0d0; } /* Name.Other */
:root[data-theme="dark"] .highlight .py { color: #d0d0d0; } /* Name.Property */
:root[data-theme="dark"] .highlight .nt { color: #6ab825; font-weight: bold } /* Name.Tag */
:root[data-theme="dark"] .highlight .nv { color: #40ffff; } /* Name.Variable */
:root[data-theme="dark"] .highlight .ow { color: #6ab825; font-weight: bold } /* Operator.Word */
:root[data-theme="dark"] .highlight .w { color: #666666; } /* Text.Whitespace */
:root[data-theme="dark"] .highlight .mf { color: #7fb1d7; } /* Literal.Number.Float */
:root[data-theme="dark"] .highlight .mh { color: #7fb1d7; } /* Literal.Number.Hex */
:root[data-theme="dark"] .highlight .mi { color: #7fb1d7; } /* Literal.Number.Integer */
:root[data-theme="dark"] .highlight .mo { color: #7fb1d7; } /* Literal.Number.Oct */
:root[data-theme="dark"] .highlight .sb { color: #ed9d13; } /* Literal.String.Backtick */
:root[data-theme="dark"] .highlight .sc { color: #ed9d13; } /* Literal.String.Char */
:root[data-theme="dark"] .highlight .sd { color: #ed9d13; } /* Literal.String.Doc */
:root[data-theme="dark"] .highlight .s2 { color: #ed9d13; } /* Literal.String.Double */
:root[data-theme="dark"] .highlight .se { color: #ed9d13; } /* Literal.String.Escape */
:root[data-theme="dark"] .highlight .sh { color: #ed9d13; } /* Literal.String.Heredoc */
:root[data-theme="dark"] .highlight .si { color: #ed9d13; } /* Literal.String.Interpol */
:root[data-theme="dark"] .highlight .sx { color: #ffa500; } /* Literal.String.Other */
:root[data-theme="dark"] .highlight .sr { color: #ed9d13; } /* Literal.String.Regex */
:root[data-theme="dark"] .highlight .s1 { color: #ed9d13; } /* Literal.String.Single */
:root[data-theme="dark"] .highlight .ss { color: #ed9d13; } /* Literal.String.Symbol */
:root[data-theme="dark"] .highlight .bp { color: #29a5b3; } /* Name.Builtin.Pseudo */
:root[data-theme="dark"] .highlight .vc { color: #40ffff; } /* Name.Variable.Class */
:root[data-theme="dark"] .highlight .vg { color: #40ffff; } /* Name.Variable.Global */
:root[data-theme="dark"] .highlight .vi { color: #40ffff; } /* Name.Variable.Instance */
:root[data-theme="dark"] .highlight .il { color: #7fb1d7; } /* Literal.Number.Integer.Long */

34
docs/_static/copy.js vendored Normal file
View File

@ -0,0 +1,34 @@
const COPY = "content_copy";
const COPIED = "done";
const copy = async (obj) => {
// <span class="copy"><span class="material-icons">{{text}}</span></span>
await navigator.clipboard.writeText(obj.children[1].innerText).then(
() => {
let icon = obj.children[0].children[0];
icon.textContent = COPIED;
setTimeout(() => (icon.textContent = COPY), 2500);
},
(r) => alert('Could not copy codeblock:\n' + r.toString())
);
};
document.addEventListener("DOMContentLoaded", () => {
let allCodeblocks = document.querySelectorAll("div[class='highlight']");
for (let codeblock of allCodeblocks) {
codeblock.parentNode.className += " relative-copy";
let copyEl = document.createElement("span");
copyEl.addEventListener('click', () => copy(codeblock));
copyEl.className = "copy";
copyEl.setAttribute("aria-label", "Copy Code");
copyEl.setAttribute("title", "Copy Code");
let copyIcon = document.createElement("span");
copyIcon.className = "material-icons";
copyIcon.textContent = COPY;
copyEl.append(copyIcon);
codeblock.prepend(copyEl);
}
});

102
docs/_static/custom.js vendored
View File

@ -1,31 +1,85 @@
$(document).ready(function () {
var sections = $('div.section');
var activeLink = null;
var bottomHeightThreshold = $(document).height() - 30;
'use-strict';
$(window).scroll(function (event) {
var distanceFromTop = $(this).scrollTop();
var currentSection = null;
let activeModal = null;
let bottomHeightThreshold, sections;
let hamburgerToggle;
let mobileSearch;
let sidebar;
if(distanceFromTop + window.innerHeight > bottomHeightThreshold) {
currentSection = $(sections[sections.length - 1]);
}
else {
sections.each(function () {
var section = $(this);
if (section.offset().top - 1 < distanceFromTop) {
currentSection = section;
}
});
}
class Modal {
constructor(element) {
this.element = element;
}
if (activeLink) {
activeLink.parent().removeClass('active');
}
close() {
activeModal = null;
this.element.style.display = 'none'
}
if (currentSection) {
activeLink = $('.sphinxsidebar a[href="#' + currentSection.attr('id') + '"]');
activeLink.parent().addClass('active');
open() {
if (activeModal) {
activeModal.close();
}
activeModal = this;
this.element.style.display = 'flex'
}
}
class SearchBar {
constructor() {
this.box = document.querySelector('nav.mobile-only');
this.bar = document.querySelector('nav.mobile-only input[type="search"]');
this.openButton = document.getElementById('open-search');
this.closeButton = document.getElementById('close-search');
}
open() {
this.openButton.hidden = true;
this.closeButton.hidden = false;
this.box.style.top = "100%";
this.bar.focus();
}
close() {
this.openButton.hidden = false;
this.closeButton.hidden = true;
this.box.style.top = "0";
}
}
document.addEventListener('DOMContentLoaded', () => {
mobileSearch = new SearchBar();
bottomHeightThreshold = document.documentElement.scrollHeight - 30;
sections = document.querySelectorAll('section');
hamburgerToggle = document.getElementById('hamburger-toggle');
if (hamburgerToggle) {
hamburgerToggle.addEventListener('click', (e) => {
sidebar.element.classList.toggle('sidebar-toggle');
let button = hamburgerToggle.firstElementChild;
if (button.textContent == 'menu') {
button.textContent = 'close';
}
else {
button.textContent = 'menu';
}
});
}
const tables = document.querySelectorAll('.py-attribute-table[data-move-to-id]');
tables.forEach(table => {
let element = document.getElementById(table.getAttribute('data-move-to-id'));
let parent = element.parentNode;
// insert ourselves after the element
parent.insertBefore(table, element.nextSibling);
});
});
document.addEventListener('keydown', (event) => {
if (event.code == "Escape" && activeModal) {
activeModal.close();
}
});

10
docs/_static/icons.css vendored Normal file
View File

@ -0,0 +1,10 @@
@font-face {
font-family: 'Custom Icons';
font-style: normal;
font-weight: 400;
src: url('icons.woff') format('woff2');
}
.custom-icons {
font-family: 'Custom Icons' !important;
}

BIN
docs/_static/icons.woff vendored Normal file

Binary file not shown.

View File

@ -1,17 +1,20 @@
var _queryBeingDone = null;
var _pattern = null;
var _escapedRegex = /[-\/\\^$*+?.()|[\]{}]/g;
'use-strict';
let queryBeingDone = null;
let pattern = null;
const escapedRegex = /[-\/\\^$*+?.()|[\]{}]/g;
function escapeRegex(e) {
return e.replace(_escapedRegex, '\\$&');
return e.replace(escapedRegex, '\\$&');
}
// for some reason Sphinx shows some entries twice
// if something has been scored already I'd rather sort it to the bottom
var _beenScored = new Set();
const beenScored = new Set();
function __score(haystack, regex) {
let match = regex.exec(haystack);
if(match == null) {
if (match == null) {
return Number.MAX_VALUE;
}
let subLength = match[0].length;
@ -24,38 +27,41 @@ function __cleanNamespaces(query) {
return query.replace(/(discord\.(ext\.)?)?(.+)/, '$3');
}
var Scorer = {
Scorer = {
// Implement the following function to further tweak the score for each result
// The function takes a result array [filename, title, anchor, descr, score]
// and returns the new score.
score: (result) => {
// only inflate the score of things that are actual API reference things
const [, title, , , score] = result;
score: function(result) {
// only inflate the score of things that are actual API reference things
if(_pattern !== null && result[1].startsWith('discord.')) {
let _score = __score(result[1], _pattern);
if(_score === Number.MAX_VALUE) {
return result[4];
if (pattern !== null && title.startsWith('discord.')) {
let _score = __score(title, pattern);
if (_score === Number.MAX_VALUE) {
return score;
}
if (beenScored.has(title)) {
return 0;
}
beenScored.add(title);
let newScore = 100 + queryBeingDone.length - _score;
// console.log(`${title}: ${score} -> ${newScore} (${_score})`);
return newScore;
}
if(_beenScored.has(result[1])) {
return 0;
}
_beenScored.add(result[1]);
let newScore = 100 + _queryBeingDone.length - _score;
// console.log(`${result[1]}: ${result[4]} -> ${newScore} (${_score})`);
return newScore;
}
return result[4];
return score;
},
// query matches the full name of an object
objNameMatch: 15,
// or matches in the last dotted part of the object name
objPartialMatch: 11,
// Additive scores depending on the priority of the object
objPrio: {0: 15, // used to be importantResults
1: 7, // used to be objectResults
2: -5}, // used to be unimportantResults
objPrio: {
0: 15, // used to be importantResults
1: 7, // used to be objectResults
2: -5 // used to be unimportantResults
},
// Used when the priority is not in the mapping.
objPrioDefault: 0,
@ -67,12 +73,11 @@ var Scorer = {
partialTerm: 2
};
$(document).ready(function() {
let params = $.getQueryParameters();
if(params.q) {
_queryBeingDone = params.q[0];
let pattern = Array.from(_queryBeingDone).map(escapeRegex).join('.*?');
_pattern = new RegExp(pattern, 'i');
document.addEventListener('DOMContentLoaded', () => {
const params = new URLSearchParams(window.location.search);
queryBeingDone = params.get('q');
if (queryBeingDone) {
let pattern = Array.from(queryBeingDone).map(escapeRegex).join('.*?');
pattern = new RegExp(pattern, 'i');
}
});

103
docs/_static/settings.js vendored Normal file
View File

@ -0,0 +1,103 @@
'use-strict';
let settingsModal;
class Setting {
constructor(name, defaultValue, setter) {
this.name = name;
this.defaultValue = defaultValue;
this.setValue = setter;
}
setElement() {
throw new TypeError('Abstract methods should be implemented.');
}
load() {
let value = JSON.parse(localStorage.getItem(this.name));
this.value = value === null ? this.defaultValue : value;
try {
this.setValue(this.value);
} catch (error) {
console.error(`Failed to apply setting "${this.name}" With value:`, this.value);
console.error(error);
}
}
update() {
throw new TypeError('Abstract methods should be implemented.');
}
}
class CheckboxSetting extends Setting {
setElement() {
let element = document.querySelector(`input[name=${this.name}]`);
element.checked = this.value;
}
update(element) {
localStorage.setItem(this.name, element.checked);
this.setValue(element.checked);
}
}
class RadioSetting extends Setting {
setElement() {
let element = document.querySelector(`input[name=${this.name}][value=${this.value}]`);
element.checked = true;
}
update(element) {
localStorage.setItem(this.name, `"${element.value}"`);
this.setValue(element.value);
}
}
function getRootAttributeToggle(attributeName, valueName) {
function toggleRootAttribute(set) {
if (set) {
document.documentElement.setAttribute(`data-${attributeName}`, valueName);
} else {
document.documentElement.removeAttribute(`data-${attributeName}`);
}
}
return toggleRootAttribute;
}
function setTheme(value) {
if (value === 'automatic') {
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.documentElement.setAttribute('data-theme', 'dark');
} else {
document.documentElement.setAttribute('data-theme', 'light');
}
}
else {
document.documentElement.setAttribute('data-theme', value);
}
}
const settings = [
new CheckboxSetting('useSerifFont', false, getRootAttributeToggle('font', 'serif')),
new RadioSetting('setTheme', 'automatic', setTheme)
]
function updateSetting(element) {
let setting = settings.find((s) => s.name == element.name);
if (setting) {
setting.update(element);
}
}
document.addEventListener('DOMContentLoaded', () => {
settingsModal = new Modal(document.querySelector('div#settings.modal'));
for (const setting of settings) {
setting.load();
setting.setElement();
}
});

127
docs/_static/sidebar.js vendored Normal file
View File

@ -0,0 +1,127 @@
class Sidebar {
constructor(element) {
this.element = element;
this.activeLink = null;
this.element.addEventListener('click', (e) => {
// If we click a navigation, close the hamburger menu
if (e.target.tagName == 'A' && this.element.classList.contains('sidebar-toggle')) {
this.element.classList.remove('sidebar-toggle');
let button = hamburgerToggle.firstElementChild;
button.textContent = 'menu';
// Scroll a little up to actually see the header
// Note: this is generally around ~55px
// A proper solution is getComputedStyle but it can be slow
// Instead let's just rely on this quirk and call it a day
// This has to be done after the browser actually processes
// the section movement
setTimeout(() => window.scrollBy(0, -100), 75);
}
});
}
createCollapsableSections() {
let toc = this.element.querySelector('ul');
if (!toc) {
return
}
let allReferences = toc.querySelectorAll('a.reference.internal:not([href="#"])');
for (let ref of allReferences) {
let next = ref.nextElementSibling;
if (next && next.tagName === "UL") {
let icon = document.createElement('span');
icon.className = 'material-icons collapsible-arrow expanded';
icon.innerText = 'expand_more';
if (next.parentElement.tagName == "LI") {
next.parentElement.classList.add('no-list-style')
}
icon.addEventListener('click', () => {
if (icon.classList.contains('expanded')) {
this.collapseSection(icon);
} else {
this.expandSection(icon);
}
})
ref.classList.add('ref-internal-padding')
ref.parentNode.insertBefore(icon, ref);
}
}
}
resize() {
let rect = this.element.getBoundingClientRect();
this.element.style.height = `calc(100vh - 1em - ${rect.top + document.body.offsetTop}px)`;
}
collapseSection(icon) {
icon.classList.remove('expanded');
icon.classList.add('collapsed');
let children = icon.nextElementSibling.nextElementSibling;
// <arrow><heading>
// --> <square><children>
setTimeout(() => children.style.display = "none", 75)
}
expandSection(icon) {
icon.classList.remove('collapse');
icon.classList.add('expanded');
let children = icon.nextElementSibling.nextElementSibling;
setTimeout(() => children.style.display = "block", 75)
}
setActiveLink(section) {
if (this.activeLink) {
this.activeLink.parentElement.classList.remove('active');
}
if (section) {
this.activeLink = document.querySelector(`#sidebar a[href="#${section.id}"]`);
if (this.activeLink) {
let headingChildren = this.activeLink.parentElement.parentElement;
let heading = headingChildren.previousElementSibling.previousElementSibling;
if (heading && headingChildren.style.display === 'none') {
this.activeLink = heading;
}
this.activeLink.parentElement.classList.add('active');
}
}
}
}
function getCurrentSection() {
let currentSection;
if (window.scrollY + window.innerHeight > bottomHeightThreshold) {
currentSection = sections[sections.length - 1];
}
else {
if (sections) {
sections.forEach(section => {
let rect = section.getBoundingClientRect();
if (rect.top + document.body.offsetTop < 1) {
currentSection = section;
}
});
}
}
return currentSection;
}
document.addEventListener('DOMContentLoaded', () => {
sidebar = new Sidebar(document.getElementById('sidebar'));
sidebar.resize();
sidebar.createCollapsableSections();
window.addEventListener('scroll', () => {
sidebar.setActiveLink(getCurrentSection());
sidebar.resize();
});
});

1241
docs/_static/style.css vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,40 +1,194 @@
{%- extends "basic/layout.html" %}
{% set show_source = False %}
{% set style = 'style.css' %}
{%- block extrahead %}
{{ super() }}
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9">
{% endblock %}
{%- block relbar2 %}{% endblock %}
{% block header %}
{{ super() }}
{% if pagename == 'index' %}
<div class="indexwrapper">
{% endif %}
{% endblock %}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title|striptags|e }}{{ titlesuffix }}</title>
{%- block extrahead %} {% endblock %}
<!-- end extra head -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="{{ pathto('_static/style.css', 1)|e }}" type="text/css" />
<link rel="stylesheet" href="{{ pathto('_static/codeblocks.css', 1) }}" type="text/css" />
<link rel="stylesheet" href="{{ pathto('_static/icons.css', 1)|e }}" type="text/css" />
{%- block css %}
{%- for css in css_files %}
{%- if css|attr("filename") %}
{{ css_tag(css) }}
{%- else %}
<link rel="stylesheet" href="{{ pathto(css, 1)|e }}" type="text/css" />
{%- endif %}
{%- endfor %}
{%- endblock %}
{%- block scripts %}
<script id="documentation_options" data-url_root="{{ pathto('', 1) }}" src="{{ pathto('_static/documentation_options.js', 1) }}"></script>
{%- for js in script_files %}
{{ js_tag(js) }}
{%- endfor %}
{%- endblock %}
{%- if pageurl %}
<link rel="canonical" href="{{ pageurl|e }}" />
{%- endif %}
{%- if favicon %}
<link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1)|e }}"/>
{%- endif %}
{%- block linktags %}
{%- if hasdoc('about') %}
<link rel="author" title="{{ _('About these documents') }}" href="{{ pathto('about') }}" />
{%- endif %}
{%- if hasdoc('genindex') %}
<link rel="index" title="{{ _('Index') }}" href="{{ pathto('genindex') }}" />
{%- endif %}
{%- if hasdoc('search') %}
<link rel="search" title="{{ _('Search') }}" href="{{ pathto('search') }}" />
{%- endif %}
{%- if hasdoc('copyright') %}
<link rel="copyright" title="{{ _('Copyright') }}" href="{{ pathto('copyright') }}" />
{%- endif %}
{%- if next %}
<link rel="next" title="{{ next.title|striptags|e }}" href="{{ next.link|e }}" />
{%- endif %}
{%- if prev %}
<link rel="prev" title="{{ prev.title|striptags|e }}" href="{{ prev.link|e }}" />
{%- endif %}
{%- endblock %}
</head>
<body>
{%- block header %}{% endblock %}
<div class="main-grid">
{#- The main navigation header #}
<header class="grid-item">
<nav>
<a href="{{ pathto(master_doc)|e }}" class="main-heading">discord.py</a>
<a href="https://github.com/Rapptz/discord.py" title="GitHub"><span class="material-icons custom-icons">github</span></a>
<a href="{{ discord_invite }}" title="{{ _('Discord') }}"><span class="material-icons custom-icons">discord</span></a>
<a href="{{ pathto('faq') }}" title="FAQ"><span class="material-icons">help_center</span></a>
{#- If we have more links we can put them here #}
<a onclick="mobileSearch.open();" title="{{ _('Search') }}" id="open-search" class="mobile-only"><span class="material-icons">search</span></a>
<a onclick="mobileSearch.close();" title="{{ _('Close') }}" id="close-search" class="mobile-only" hidden><span class="material-icons">close</span></a>
</nav>
<nav class="mobile-only">
<form role="search" class="search" action="search.html" method="get">
<div class="search-wrapper">
<input type="search" name="q" placeholder="{{ _('Search documentation') }}" />
<button type="submit">
<span class="material-icons">search</span>
</button>
</div>
</form>
</nav>
</header>
{#- The sub-header with search and extension related selection #}
<div class="sub-header grid-item">
<label for="documentation_select">{{ _('View Documentation For') }}</label>
<select id="documentation_select" onchange="window.location = this.value;">
{%- if pagename is prefixedwith 'ext/' %}
<option value="{{ pathto(master_doc)|e }}">discord</option>
{%- else %}
<option value="{{ pathto(pagename) }}" selected>discord</option>
{%- endif %}
{%- for ext, p in discord_extensions %}
<option value="{{ pathto(p + '/index')|e }}" {% if pagename is prefixedwith p %}selected{% endif %}>{{ ext }}</option>
{%- endfor %}
</select>
<form role="search" class="search" action="search.html" method="get">
<div class="search-wrapper">
<input type="search" name="q" placeholder="{{ _('Search documentation') }}" />
<button type="submit">
<span class="material-icons">search</span>
</button>
</div>
</form>
<a accesskey="S" class="settings" onclick="settingsModal.open();"><span class="material-icons">settings</span></a>
</div>
{#- The sidebar component #}
<aside class="grid-item">
{%- if display_toc %}
<span id="hamburger-toggle">
<span class="material-icons">menu</span>
</span>
{%- endif %}
<span id="settings-toggle" class="settings" onclick="settingsModal.open();">
<span class="material-icons">settings</span>
</span>
<div id="sidebar">
{%- include "localtoc.html" %}
</div>
</aside>
{#- The actual body of the contents #}
<main class="grid-item">
{% block body %} {% endblock %}
</main>
{%- block footer %}
<div class="footer">
&copy; Copyright {{ copyright }}.
{% trans sphinx_version=sphinx_version|e %}Created using <a href="http://sphinx-doc.org/">Sphinx</a> {{ sphinx_version }}.{% endtrans %}
<footer class="grid-item">
{%- if show_copyright %}
{%- if hasdoc('copyright') %}
{% trans path=pathto('copyright'), copyright=copyright|e %}&#169; <a href="{{ path }}">Copyright</a> {{ copyright }}.{% endtrans %}
{%- else %}
{% trans copyright=copyright|e %}&#169; Copyright {{ copyright }}.{% endtrans %}
{%- endif %}
{%- endif %}
{%- if last_updated %}
{% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %}
{%- endif %}
{%- if show_sphinx %}
{% trans sphinx_version=sphinx_version|e %}Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> {{ sphinx_version }}.{% endtrans %}
{%- endif %}
</footer>
{%- endblock %}
</div>
{% if pagename == 'index' %}
</div>
{% endif %}
{%- if READTHEDOCS %}
<script>
if (typeof READTHEDOCS_DATA !== 'undefined') {
if (typeof READTHEDOCS_DATA !== "undefined") {
if (!READTHEDOCS_DATA.features) {
READTHEDOCS_DATA.features = {};
}
READTHEDOCS_DATA.features.docsearch_disabled = true;
}
</script>
</script>
{%- endif %}
{%- endblock %}
<div id="settings" class="modal" onclick="if (event.target == this){ settingsModal.close(); }" hidden>
<div class="modal-content">
<span class="close" onclick="settingsModal.close();" title="Close">
<span class="material-icons">close</span>
</span>
<h1>{{ _('Settings') }}</h1>
<h2>{{ _('Font') }}</h2>
<div class="setting">
<h3>{{ _('Use a serif font:') }}
<label class="toggle"
title="{{ _('Use a serif font? Your system font will be used, falling back to serif.')}}">
<input type="checkbox" name="useSerifFont" onclick="updateSetting(this);">
<span class="toggle-slider"></span>
</label>
</h3>
</div>
<h2>{{ _('Theme') }}</h2>
<div class="setting">
<h3>
<label class="toggle" title="{{ _('Set your theme based on your system preferences') }}">
<input type="radio" name="setTheme" onclick="updateSetting(this);" value="automatic" checked>
</label>
{{ _('Automatic') }}
</h3>
<h3>
<label class="toggle" title="{{ _('Set your theme to light theme') }}">
<input type="radio" name="setTheme" onclick="updateSetting(this);" value="light">
</label>
{{ _('Light') }}
</h3>
<h3>
<label class="toggle" title="{{ _('Set your theme to dark theme') }}">
<input type="radio" name="setTheme" onclick="updateSetting(this);" value="dark">
</label>
{{ _('Dark') }}
</h3>
</div>
</div>
</div>
</body>
</html>

View File

@ -30,48 +30,108 @@ There are two main ways to query version information about the library. For guar
A string representation of the version. e.g. ``'1.0.0rc1'``. This is based
off of :pep:`440`.
Clients
--------
Client
-------
~~~~~~~
.. attributetable:: Client
.. autoclass:: Client
:members:
AutoShardedClient
~~~~~~~~~~~~~~~~~~
.. attributetable:: AutoShardedClient
.. autoclass:: AutoShardedClient
:members:
Application Info
------------------
AppInfo
~~~~~~~~
.. attributetable:: AppInfo
.. autoclass:: AppInfo()
:members:
Team
~~~~~
.. attributetable:: Team
.. autoclass:: Team()
:members:
TeamMember
~~~~~~~~~~~
.. attributetable:: TeamMember
.. autoclass:: TeamMember()
:members:
Voice
------
Voice Related
---------------
VoiceClient
~~~~~~~~~~~~
.. attributetable:: VoiceClient
.. autoclass:: VoiceClient()
:members:
.. autoclass:: VoiceProtocol
:members:
AudioSource
~~~~~~~~~~~~
.. attributetable:: AudioSource
.. autoclass:: AudioSource
:members:
PCMAudio
~~~~~~~~~
.. attributetable:: PCMAudio
.. autoclass:: PCMAudio
:members:
FFmpegAudio
~~~~~~~~~~~~
.. attributetable:: FFmpegAudio
.. autoclass:: FFmpegAudio
:members:
FFmpegPCMAudio
~~~~~~~~~~~~~~~
.. attributetable:: FFmpegPCMAudio
.. autoclass:: FFmpegPCMAudio
:members:
FFmpegOpusAudio
~~~~~~~~~~~~~~~~
.. attributetable:: FFmpegOpusAudio
.. autoclass:: FFmpegOpusAudio
:members:
PCMVolumeTransformer
~~~~~~~~~~~~~~~~~~~~~
.. attributetable:: PCMVolumeTransformer
.. autoclass:: PCMVolumeTransformer
:members:
@ -2036,9 +2096,19 @@ Working with :meth:`Guild.audit_logs` is a complicated process with a lot of mac
involved. The library attempts to make it easy to use and friendly. In order to accomplish
this goal, it must make use of a couple of data classes that aid in this goal.
AuditLogEntry
~~~~~~~~~~~~~~~
.. attributetable:: AuditLogEntry
.. autoclass:: AuditLogEntry
:members:
AuditLogChanges
~~~~~~~~~~~~~~~~~
.. attributetable:: AuditLogChanges
.. class:: AuditLogChanges
An audit log change set.
@ -2083,6 +2153,11 @@ this goal, it must make use of a couple of data classes that aid in this goal.
| ``None`` | No attributes are set. |
+----------------------------------------+--------------------------------------------------+
AuditLogDiff
~~~~~~~~~~~~~
.. attributetable:: AuditLogDiff
.. class:: AuditLogDiff
Represents an audit log "change" object. A change object has dynamic
@ -2428,6 +2503,8 @@ Webhook Support
discord.py offers support for creating, editing, and executing webhooks through the :class:`Webhook` class.
.. attributetable:: Webhook
.. autoclass:: Webhook
:members:
@ -2459,18 +2536,43 @@ They are mainly there for usage with :func:`py:isinstance` and :func:`py:issubcl
This library has a module related to abstract base classes, some of which are actually from the :doc:`abc <py:library/abc>` standard
module, others which are not.
Snowflake
~~~~~~~~~~
.. attributetable:: discord.abc.Snowflake
.. autoclass:: discord.abc.Snowflake
:members:
User
~~~~~
.. attributetable:: discord.abc.User
.. autoclass:: discord.abc.User
:members:
PrivateChannel
~~~~~~~~~~~~~~~
.. attributetable:: discord.abc.PrivateChannel
.. autoclass:: discord.abc.PrivateChannel
:members:
GuildChannel
~~~~~~~~~~~~~
.. attributetable:: discord.abc.GuildChannel
.. autoclass:: discord.abc.GuildChannel
:members:
Messageable
~~~~~~~~~~~~
.. attributetable:: discord.abc.Messageable
.. autoclass:: discord.abc.Messageable
:members:
:exclude-members: history, typing
@ -2481,6 +2583,11 @@ module, others which are not.
.. automethod:: discord.abc.Messageable.typing
:async-with:
Connectable
~~~~~~~~~~~~
.. attributetable:: discord.abc.Connectable
.. autoclass:: discord.abc.Connectable
.. _discord_api_models:
@ -2513,6 +2620,8 @@ the user of the library.
ClientUser
~~~~~~~~~~~~
.. attributetable:: ClientUser
.. autoclass:: ClientUser()
:members:
:inherited-members:
@ -2520,12 +2629,16 @@ ClientUser
Relationship
~~~~~~~~~~~~~~
.. attributetable:: Relationship
.. autoclass:: Relationship()
:members:
User
~~~~~
.. attributetable:: User
.. autoclass:: User()
:members:
:inherited-members:
@ -2540,24 +2653,32 @@ User
Attachment
~~~~~~~~~~~
.. attributetable:: Attachment
.. autoclass:: Attachment()
:members:
Asset
~~~~~
.. attributetable:: Asset
.. autoclass:: Asset()
:members:
Message
~~~~~~~
.. attributetable:: Message
.. autoclass:: Message()
:members:
Reaction
~~~~~~~~~
.. attributetable:: Reaction
.. autoclass:: Reaction()
:members:
:exclude-members: users
@ -2568,18 +2689,24 @@ Reaction
CallMessage
~~~~~~~~~~~~
.. attributetable:: CallMessage
.. autoclass:: CallMessage()
:members:
GroupCall
~~~~~~~~~~
.. attributetable:: GroupCall
.. autoclass:: GroupCall()
:members:
Guild
~~~~~~
.. attributetable:: Guild
.. autoclass:: Guild()
:members:
:exclude-members: audit_logs
@ -2599,6 +2726,8 @@ Integration
Member
~~~~~~
.. attributetable:: Member
.. autoclass:: Member()
:members:
:inherited-members:
@ -2613,36 +2742,48 @@ Member
Spotify
~~~~~~~~
.. attributetable:: Spotify
.. autoclass:: Spotify()
:members:
VoiceState
~~~~~~~~~~~
.. attributetable:: VoiceState
.. autoclass:: VoiceState()
:members:
Emoji
~~~~~
.. attributetable:: Emoji
.. autoclass:: Emoji()
:members:
PartialEmoji
~~~~~~~~~~~~~~~~~~~~~~
.. attributetable:: PartialEmoji
.. autoclass:: PartialEmoji()
:members:
Role
~~~~~
.. attributetable:: Role
.. autoclass:: Role()
:members:
TextChannel
~~~~~~~~~~~~
.. attributetable:: TextChannel
.. autoclass:: TextChannel()
:members:
:inherited-members:
@ -2657,6 +2798,8 @@ TextChannel
VoiceChannel
~~~~~~~~~~~~~
.. attributetable:: VoiceChannel
.. autoclass:: VoiceChannel()
:members:
:inherited-members:
@ -2664,6 +2807,8 @@ VoiceChannel
CategoryChannel
~~~~~~~~~~~~~~~~~
.. attributetable:: CategoryChannel
.. autoclass:: CategoryChannel()
:members:
:inherited-members:
@ -2671,6 +2816,8 @@ CategoryChannel
DMChannel
~~~~~~~~~
.. attributetable:: DMChannel
.. autoclass:: DMChannel()
:members:
:inherited-members:
@ -2685,6 +2832,8 @@ DMChannel
GroupChannel
~~~~~~~~~~~~
.. attributetable:: GroupChannel
.. autoclass:: GroupChannel()
:members:
:inherited-members:
@ -2699,18 +2848,24 @@ GroupChannel
PartialInviteGuild
~~~~~~~~~~~~~~~~~~~
.. attributetable:: PartialInviteGuild
.. autoclass:: PartialInviteGuild()
:members:
PartialInviteChannel
~~~~~~~~~~~~~~~~~~~~~
.. attributetable:: PartialInviteChannel
.. autoclass:: PartialInviteChannel()
:members:
Invite
~~~~~~~
.. attributetable:: Invite
.. autoclass:: Invite()
:members:
@ -2723,12 +2878,16 @@ Template
WidgetChannel
~~~~~~~~~~~~~~~
.. attributetable:: WidgetChannel
.. autoclass:: WidgetChannel()
:members:
WidgetMember
~~~~~~~~~~~~~
.. attributetable:: WidgetMember
.. autoclass:: WidgetMember()
:members:
:inherited-members:
@ -2736,6 +2895,8 @@ WidgetMember
Widget
~~~~~~~
.. attributetable:: Widget
.. autoclass:: Widget()
:members:
@ -2747,36 +2908,48 @@ MessageReference
RawMessageDeleteEvent
~~~~~~~~~~~~~~~~~~~~~~~
.. attributetable:: RawMessageDeleteEvent
.. autoclass:: RawMessageDeleteEvent()
:members:
RawBulkMessageDeleteEvent
~~~~~~~~~~~~~~~~~~~~~~~~~~
.. attributetable:: RawBulkMessageDeleteEvent
.. autoclass:: RawBulkMessageDeleteEvent()
:members:
RawMessageUpdateEvent
~~~~~~~~~~~~~~~~~~~~~~
.. attributetable:: RawMessageUpdateEvent
.. autoclass:: RawMessageUpdateEvent()
:members:
RawReactionActionEvent
~~~~~~~~~~~~~~~~~~~~~~~
.. attributetable:: RawReactionActionEvent
.. autoclass:: RawReactionActionEvent()
:members:
RawReactionClearEvent
~~~~~~~~~~~~~~~~~~~~~~
.. attributetable:: RawReactionClearEvent
.. autoclass:: RawReactionClearEvent()
:members:
RawReactionClearEmojiEvent
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. attributetable:: RawReactionClearEmojiEvent
.. autoclass:: RawReactionClearEmojiEvent()
:members:
@ -2807,12 +2980,16 @@ Object
Embed
~~~~~~
.. attributetable:: Embed
.. autoclass:: Embed
:members:
AllowedMentions
~~~~~~~~~~~~~~~~~
.. attributetable:: AllowedMentions
.. autoclass:: AllowedMentions
:members:
@ -2831,54 +3008,72 @@ MemberCacheFlags
File
~~~~~
.. attributetable:: File
.. autoclass:: File
:members:
Colour
~~~~~~
.. attributetable:: Colour
.. autoclass:: Colour
:members:
BaseActivity
~~~~~~~~~~~~~~
.. attributetable:: BaseActivity
.. autoclass:: BaseActivity
:members:
Activity
~~~~~~~~~
.. attributetable:: Activity
.. autoclass:: Activity
:members:
Game
~~~~~
.. attributetable:: Game
.. autoclass:: Game
:members:
Streaming
~~~~~~~~~~~
.. attributetable:: Streaming
.. autoclass:: Streaming
:members:
CustomActivity
~~~~~~~~~~~~~~~
.. attributetable:: CustomActivity
.. autoclass:: CustomActivity
:members:
Permissions
~~~~~~~~~~~~
.. attributetable:: Permissions
.. autoclass:: Permissions
:members:
PermissionOverwrite
~~~~~~~~~~~~~~~~~~~~
.. attributetable:: PermissionOverwrite
.. autoclass:: PermissionOverwrite
:members:

View File

@ -38,7 +38,8 @@ extensions = [
'sphinx.ext.napoleon',
'sphinxcontrib_trio',
'details',
'exception_hierarchy'
'exception_hierarchy',
'attributetable',
]
autodoc_member_order = 'bysource'
@ -143,6 +144,14 @@ html_experimental_html5_writer = True
# a list of builtin themes.
html_theme = 'basic'
html_context = {
'discord_invite': 'https://discord.gg/r3sSKJJ',
'discord_extensions': [
('discord.ext.commands', 'ext/commands'),
('discord.ext.tasks', 'ext/tasks'),
],
}
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
@ -166,7 +175,7 @@ html_theme = 'basic'
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
html_favicon = './images/discord_py_logo.ico'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
@ -233,6 +242,13 @@ html_static_path = ['_static']
# implements a search results scorer. If empty, the default will be used.
html_search_scorer = '_static/scorer.js'
html_js_files = [
'custom.js',
'settings.js',
'copy.js',
'sidebar.js'
]
# Output file base name for HTML help builder.
htmlhelp_basename = 'discord.pydoc'
@ -318,6 +334,6 @@ texinfo_documents = [
#texinfo_no_detailmenu = False
def setup(app):
app.add_js_file('custom.js')
if app.config.language == 'ja':
app.config.intersphinx_mapping['py'] = ('https://docs.python.org/ja/3', None)
app.config.html_context['discord_invite'] = 'https://discord.gg/nXzj3dg'

View File

@ -0,0 +1,241 @@
from sphinx.util.docutils import SphinxDirective
from sphinx.locale import _
from docutils import nodes
from sphinx import addnodes
from collections import OrderedDict, namedtuple
import importlib
import inspect
import os
import re
class attributetable(nodes.General, nodes.Element):
pass
class attributetablecolumn(nodes.General, nodes.Element):
pass
class attributetabletitle(nodes.TextElement):
pass
class attributetableplaceholder(nodes.General, nodes.Element):
pass
class attributetablebadge(nodes.TextElement):
pass
class attributetable_item(nodes.Part, nodes.Element):
pass
def visit_attributetable_node(self, node):
self.body.append('<div class="py-attribute-table" data-move-to-id="%s">' % node['python-class'])
def visit_attributetablecolumn_node(self, node):
self.body.append(self.starttag(node, 'div', CLASS='py-attribute-table-column'))
def visit_attributetabletitle_node(self, node):
self.body.append(self.starttag(node, 'span'))
def visit_attributetablebadge_node(self, node):
attributes = {
'class': 'py-attribute-table-badge',
'title': node['badge-type'],
}
self.body.append(self.starttag(node, 'span', **attributes))
def visit_attributetable_item_node(self, node):
self.body.append(self.starttag(node, 'li', CLASS='py-attribute-table-entry'))
def depart_attributetable_node(self, node):
self.body.append('</div>')
def depart_attributetablecolumn_node(self, node):
self.body.append('</div>')
def depart_attributetabletitle_node(self, node):
self.body.append('</span>')
def depart_attributetablebadge_node(self, node):
self.body.append('</span>')
def depart_attributetable_item_node(self, node):
self.body.append('</li>')
_name_parser_regex = re.compile(r'(?P<module>[\w.]+\.)?(?P<name>\w+)')
class PyAttributeTable(SphinxDirective):
has_content = False
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = False
option_spec = {}
def parse_name(self, content):
path, name = _name_parser_regex.match(content).groups()
if path:
modulename = path.rstrip('.')
else:
modulename = self.env.temp_data.get('autodoc:module')
if not modulename:
modulename = self.env.ref_context.get('py:module')
if modulename is None:
raise RuntimeError('modulename somehow None for %s in %s.' % (content, self.env.docname))
return modulename, name
def run(self):
"""If you're curious on the HTML this is meant to generate:
<div class="py-attribute-table">
<div class="py-attribute-table-column">
<span>_('Attributes')</span>
<ul>
<li>
<a href="...">
</li>
</ul>
</div>
<div class="py-attribute-table-column">
<span>_('Methods')</span>
<ul>
<li>
<a href="..."></a>
<span class="py-attribute-badge" title="decorator">D</span>
</li>
</ul>
</div>
</div>
However, since this requires the tree to be complete
and parsed, it'll need to be done at a different stage and then
replaced.
"""
content = self.arguments[0].strip()
node = attributetableplaceholder('')
modulename, name = self.parse_name(content)
node['python-module'] = modulename
node['python-class'] = name
node['python-full-name'] = '%s.%s' % (modulename, name)
return [node]
def build_lookup_table(env):
# Given an environment, load up a lookup table of
# full-class-name: objects
result = {}
domain = env.domains['py']
ignored = {
'data', 'exception', 'module', 'class',
}
for (fullname, _, objtype, docname, _, _) in domain.get_objects():
if objtype in ignored:
continue
classname, _, child = fullname.rpartition('.')
try:
result[classname].append(child)
except KeyError:
result[classname] = [child]
return result
TableElement = namedtuple('TableElement', 'fullname label badge')
def process_attributetable(app, doctree, fromdocname):
env = app.builder.env
lookup = build_lookup_table(env)
for node in doctree.traverse(attributetableplaceholder):
modulename, classname, fullname = node['python-module'], node['python-class'], node['python-full-name']
groups = get_class_results(lookup, modulename, classname, fullname)
table = attributetable('')
for label, subitems in groups.items():
if not subitems:
continue
table.append(class_results_to_node(label, sorted(subitems, key=lambda c: c.label)))
table['python-class'] = fullname
if not table:
node.replace_self([])
else:
node.replace_self([table])
def get_class_results(lookup, modulename, name, fullname):
module = importlib.import_module(modulename)
cls = getattr(module, name)
groups = OrderedDict([
(_('Attributes'), []),
(_('Methods'), []),
])
try:
members = lookup[fullname]
except KeyError:
return groups
for attr in members:
attrlookup = '%s.%s' % (fullname, attr)
key = _('Attributes')
badge = None
label = attr
for base in cls.__mro__:
value = base.__dict__.get(attr)
if value is not None:
break
if value is not None:
doc = value.__doc__ or ''
if inspect.iscoroutinefunction(value) or doc.startswith('|coro|'):
key = _('Methods')
badge = attributetablebadge('async', 'async')
badge['badge-type'] = _('coroutine')
elif isinstance(value, classmethod):
key = _('Methods')
label = '%s.%s' % (name, attr)
badge = attributetablebadge('cls', 'cls')
badge['badge-type'] = _('classmethod')
elif inspect.isfunction(value):
if doc.startswith(('A decorator', 'A shortcut decorator')):
# finicky but surprisingly consistent
badge = attributetablebadge('@', '@')
badge['badge-type'] = _('decorator')
key = _('Methods')
else:
key = _('Methods')
badge = attributetablebadge('def', 'def')
badge['badge-type'] = _('method')
groups[key].append(TableElement(fullname=attrlookup, label=label, badge=badge))
return groups
def class_results_to_node(key, elements):
title = attributetabletitle(key, key)
ul = nodes.bullet_list('')
for element in elements:
ref = nodes.reference('', '', internal=True,
refuri='#' + element.fullname,
anchorname='',
*[nodes.Text(element.label)])
para = addnodes.compact_paragraph('', '', ref)
if element.badge is not None:
ul.append(attributetable_item('', element.badge, para))
else:
ul.append(attributetable_item('', para))
return attributetablecolumn('', title, ul)
def setup(app):
app.add_directive('attributetable', PyAttributeTable)
app.add_node(attributetable, html=(visit_attributetable_node, depart_attributetable_node))
app.add_node(attributetablecolumn, html=(visit_attributetablecolumn_node, depart_attributetablecolumn_node))
app.add_node(attributetabletitle, html=(visit_attributetabletitle_node, depart_attributetabletitle_node))
app.add_node(attributetablebadge, html=(visit_attributetablebadge_node, depart_attributetablebadge_node))
app.add_node(attributetable_item, html=(visit_attributetable_item_node, depart_attributetable_item_node))
app.add_node(attributetableplaceholder)
app.connect('doctree-resolved', process_attributetable)

View File

@ -1,5 +1,24 @@
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.environment.adapters.indexentries import IndexEntries
from sphinx.writers.html5 import HTML5Translator
class DPYHTML5Translator(HTML5Translator):
def visit_section(self, node):
self.section_level += 1
self.body.append(
self.starttag(node, 'section'))
def depart_section(self, node):
self.section_level -= 1
self.body.append('</section>\n')
def visit_table(self, node):
self.body.append('<div class="table-wrapper">')
super().visit_table(node)
def depart_table(self, node):
super().depart_table(node)
self.body.append('</div>')
class DPYStandaloneHTMLBuilder(StandaloneHTMLBuilder):
# This is mostly copy pasted from Sphinx.
@ -31,16 +50,26 @@ class DPYStandaloneHTMLBuilder(StandaloneHTMLBuilder):
else:
self.handle_page('genindex', genindexcontext, 'genindex.html')
def get_builder(app):
def add_custom_jinja2(app):
env = app.builder.templates.environment
env.tests['prefixedwith'] = str.startswith
env.tests['suffixedwith'] = str.endswith
def add_builders(app):
"""This is necessary because RTD injects their own for some reason."""
try:
original = app.registry.builders['readthedocs']
except KeyError:
return DPYStandaloneHTMLBuilder
app.set_translator('html', DPYHTML5Translator, override=True)
app.add_builder(DPYStandaloneHTMLBuilder, override=True)
else:
injected_mro = tuple(base if base is not StandaloneHTMLBuilder else DPYStandaloneHTMLBuilder
for base in original.mro()[1:])
return type(original.__name__, injected_mro, {'name': 'readthedocs'})
new_builder = type(original.__name__, injected_mro, {'name': 'readthedocs'})
app.set_translator('readthedocs', DPYHTML5Translator, override=True)
app.add_builder(new_builder, override=True)
def setup(app):
app.add_builder(get_builder(app), override=True)
add_builders(app)
app.connect('builder-inited', add_custom_jinja2)

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 KiB

View File

@ -0,0 +1,4 @@
<svg fill='white' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'>
<path d='M7 10l5 5 5-5z'/>
<path d='M0 0h24v24H0z' fill='none'/>
</svg>

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

17
docs/images/snake.svg Normal file
View File

@ -0,0 +1,17 @@
<svg style="width: 100%; height: 100%"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1036 597.33331" height="597.333" width="1036">
<path d="M498.46 84.248c-1.6 1.665-2.4 3.597-2.4 5.93 0 2.333.8 4.265 2.4 5.863 1.667 1.67 3.6 2.47 5.932 2.47 2.332 0 4.265-.8 5.864-2.46 1.665-1.59 2.465-3.53 2.465-5.86 0-2.33-.8-4.26-2.46-5.93-1.6-1.6-3.53-2.4-5.86-2.4s-4.26.8-5.93 2.4m-9.06 5.93c0-2.33-.8-4.26-2.46-5.93-1.6-1.6-3.53-2.4-5.862-2.4s-4.265.8-5.93 2.4c-1.6 1.67-2.4 3.6-2.4 5.93 0 2.33.8 4.27 2.4 5.86 1.665 1.67 3.598 2.47 5.93 2.47s4.265-.8 5.864-2.46c1.663-1.593 2.463-3.53 2.463-5.86m46.647 0c0-2.333-.8-4.27-2.467-5.93-1.6-1.6-3.53-2.4-5.86-2.4s-4.265.8-5.93 2.4c-1.6 1.665-2.4 3.597-2.4 5.93 0 2.333.8 4.265 2.4 5.863 1.665 1.67 3.598 2.467 5.93 2.467s4.265-.8 5.864-2.468c1.667-1.598 2.467-3.53 2.467-5.86" fill="#e0e0e0"/>
<path d="M2748.2-850.22H155.382c-76.964 0-115.447-48.474-115.447-144.932V-4303.65c0-96.45 38.483-144.93 115.447-144.93H6321.57c76.97 0 115.45 48.48 115.45 144.93v3308.498c0 96.458-38.48 144.933-115.45 144.933H3737.75" fill="none" stroke="#e0e0e0" stroke-width="79.964" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
<path d="M4177.05-3798.87v2178.5H998.996v-2178.5c0-133.44 66.474-199.91 199.914-199.91h2778.23c133.44 0 199.91 66.47 199.91 199.91z" fill="none" stroke="#e0e0e0" stroke-width="79.964" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
<path d="M6274.1-4181.2v2844.7c0 82.97-36.49 124.45-108.95 124.45H322.307c-72.47 0-108.952-41.48-108.952-124.45v-2844.7c0-82.96 36.483-124.44 108.952-124.44H6165.15c72.46 0 108.95 41.48 108.95 124.44zM449.25-41.084h147.43m182.418 0h339.842m1407.86 0c0-91.458 46.98-151.43 140.94-179.92 23.99-7.497 50.97-12.493 80.46-15.993m0 0c24.49-2.497 51.48-3.997 79.96-3.997h820.63c32.49 0 61.97 2 88.96 5.497M1348.84-41.084H2526.8m221.4-195.913V-850.22m989.55 614.723c26.49 3 49.98 7.996 71.47 14.493 93.96 28.49 140.93 88.462 140.93 179.92m2024.08 0h50.98m-468.28 0h219.89m-1826.67 0h1416.86M3737.75-235.497V-850.22m212.4 809.136H2526.8M3737.75-850.22H2748.2" fill="none" stroke="#e0e0e0" stroke-width="79.964" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
<path d="M2126.79-2789.58c-38.13 38.49-57.37 85.01-57.37 139.59 0 54.22 19.24 100.75 57.37 139.23 38.48 38.48 85.01 57.73 139.59 57.73 54.22 0 100.75-19.25 139.23-57.73 38.49-38.48 57.73-85.01 57.73-139.23 0-54.58-19.24-101.1-57.73-139.59-38.48-38.13-85.01-57.37-139.23-57.37-54.58 0-101.11 19.24-139.59 57.37z" fill="none" stroke="#e0e0e0" stroke-width="69.967" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
<path d="M2640.7-3448.32c-286.51-11.2-546.09 38.83-778.73 150.43 143.08-106.7 307.5-172.47 493.27-197.66-6.3-14.34-18.9-29.04-38.13-43.73h-62.98c-210.25 36.73-380.62 103.9-511.11 201.16-197.66 325.7-291.76 678.68-281.62 1058.6 142.39 189.97 349.49 279.53 621.31 267.98l122.45-129.44c-148.68-52.82-255.03-123.49-318.7-212 214.1 133.99 465.63 199.41 754.24 196.26" fill="none" stroke="#e0e0e0" stroke-width="69.967" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
<path d="M-3149.74-2789.58c-38.13 38.49-57.37 85.01-57.37 139.59 0 54.22 19.24 100.75 57.37 139.23 38.49 38.48 85.01 57.73 139.59 57.73 54.22 0 100.75-19.25 139.23-57.73 38.49-38.48 57.73-85.01 57.73-139.23 0-54.58-19.24-101.1-57.73-139.59-38.48-38.13-85.01-57.37-139.23-57.37-54.58 0-101.1 19.24-139.59 57.37z" fill="none" stroke="#e0e0e0" stroke-width="69.967" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(-.13334 0 0 .13333 0 597.333)"/>
<path d="M-2635.83-3448.32c-286.51-11.2-546.09 38.83-778.73 150.43 143.08-106.7 307.5-172.47 493.27-197.66-6.3-14.34-18.89-29.04-38.13-43.73h-62.98c-210.25 36.73-380.62 103.9-511.11 201.16-197.66 325.7-291.76 678.68-281.62 1058.6 142.39 189.97 349.49 279.53 621.32 267.98l122.44-129.44c-148.68-52.82-255.03-123.49-318.7-212 214.1 133.99 465.63 199.41 754.24 196.26" fill="none" stroke="#e0e0e0" stroke-width="69.967" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(-.13334 0 0 .13333 0 597.333)"/>
<path d="M474.47 230.785c-17.793 0-26.655 8.863-26.655 26.654v261.2-23.99H207.912h47.98v-58.9 34.91h143.94-47.98v23.99h95.963v-94.88c-.534-16.73-9.396-25.06-26.656-25.06H186.58c-17.792 0-26.656 8.86-26.656 26.65v163.85c0 17.26 8.33 26.12 25.057 26.65h333.8c16.66-.53 24.99-9.39 24.99-26.65V326.74h-34.65c-16.66.667-24.65-7.33-23.99-23.987h300.28c4.2-7.13 6.27-15.126 6.27-23.99v-21.32c0-17.792-8.86-26.655-26.65-26.655zm-13.327 311.842l23.99 22.588-23.99-22.588" fill="#eadc62"/>
<path d="M777.616 312.677c3.132-3.132 5.73-6.397 7.796-9.928h-300.28c-.665 16.65 7.33 24.65 23.992 23.98h234.572c13.26 0 24.523-4.67 33.92-14.06" fill="#f2edc8"/>
<path d="M3890.68-40.99H1387.32m1971.1-1440.85v-1067.51c0-133.44 66.47-199.91 199.91-199.91h2179.01c133.44 0 199.91 66.47 199.91 199.91v159.93c0 66.47-15.49 126.44-46.98 179.92" fill="none" stroke="#000" stroke-width="79.964" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
<path d="M5890.27-2209.5c-15.49 26.48-34.98 50.97-58.47 74.46-70.47 70.47-154.93 105.45-254.39 105.45H4078.1M3358.42-590.243V-770.16m719.68-1259.43h-259.88m-459.8 1259.43v-711.68M3638.3-240.9l-179.92-169.423M4449.93-40.99h-559.25m187.42-1988.6V-240.9c0 129.44-62.48 195.91-187.42 199.91m1007.04 0H4717.8M1559.24-770.16h359.84m4777.83-1259.43l-179.92-179.91m0 0l179.92-179.92M949.022-40.99h438.298M6516.99-2209.5h-626.72m-3971.19 997.54v261.88m0 0v179.92m1079.51-179.92h-359.84m0 0v179.92m-719.67-179.92h719.67m0 179.92h-719.67M1387.32-40.99c-125.44-4-187.91-70.47-187.91-199.91v-1228.94c0-133.44 66.47-199.91 199.9-199.91h1759.2c129.45 0 195.92 62.47 199.91 187.91m-719.67 711.68h719.67" fill="none" stroke="#000" stroke-width="79.964" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
<path d="M7716.44-2209.5H7356.6m0 539.75l-179.92-179.92m179.92-899.59l-179.92 179.92" fill="none" stroke="#e0e0e0" stroke-width="99.954" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
<path d="M769.485 258.24c-2.332-2.333-5.13-3.467-8.462-3.467s-6.198 1.134-8.53 3.466c-2.333 2.33-3.466 5.19-3.466 8.52s1.133 6.13 3.466 8.46c2.332 2.33 5.198 3.53 8.53 3.53 3.332 0 6.13-1.2 8.462-3.53 2.334-2.34 3.532-5.13 3.532-8.47 0-3.33-1.198-6.2-3.532-8.53"/>
</svg>

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -0,0 +1,17 @@
<svg style="width: 100%; height: 100%"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1036 597.33331" height="597.333" width="1036">
<path d="M498.46 84.248c-1.6 1.665-2.4 3.597-2.4 5.93 0 2.333.8 4.265 2.4 5.863 1.667 1.67 3.6 2.47 5.932 2.47 2.332 0 4.265-.8 5.864-2.46 1.665-1.59 2.465-3.53 2.465-5.86 0-2.33-.8-4.26-2.46-5.93-1.6-1.6-3.53-2.4-5.86-2.4s-4.26.8-5.93 2.4m-9.06 5.93c0-2.33-.8-4.26-2.46-5.93-1.6-1.6-3.53-2.4-5.862-2.4s-4.265.8-5.93 2.4c-1.6 1.67-2.4 3.6-2.4 5.93 0 2.33.8 4.27 2.4 5.86 1.665 1.67 3.598 2.47 5.93 2.47s4.265-.8 5.864-2.46c1.663-1.593 2.463-3.53 2.463-5.86m46.647 0c0-2.333-.8-4.27-2.467-5.93-1.6-1.6-3.53-2.4-5.86-2.4s-4.265.8-5.93 2.4c-1.6 1.665-2.4 3.597-2.4 5.93 0 2.333.8 4.265 2.4 5.863 1.665 1.67 3.598 2.467 5.93 2.467s4.265-.8 5.864-2.468c1.667-1.598 2.467-3.53 2.467-5.86" fill="#161616"/>
<path d="M2748.2-850.22H155.382c-76.964 0-115.447-48.474-115.447-144.932V-4303.65c0-96.45 38.483-144.93 115.447-144.93H6321.57c76.97 0 115.45 48.48 115.45 144.93v3308.498c0 96.458-38.48 144.933-115.45 144.933H3737.75" fill="none" stroke="#161616" stroke-width="79.964" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
<path d="M4177.05-3798.87v2178.5H998.996v-2178.5c0-133.44 66.474-199.91 199.914-199.91h2778.23c133.44 0 199.91 66.47 199.91 199.91z" fill="none" stroke="#161616" stroke-width="79.964" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
<path d="M6274.1-4181.2v2844.7c0 82.97-36.49 124.45-108.95 124.45H322.307c-72.47 0-108.952-41.48-108.952-124.45v-2844.7c0-82.96 36.483-124.44 108.952-124.44H6165.15c72.46 0 108.95 41.48 108.95 124.44zM449.25-41.084h147.43m182.418 0h339.842m1407.86 0c0-91.458 46.98-151.43 140.94-179.92 23.99-7.497 50.97-12.493 80.46-15.993m0 0c24.49-2.497 51.48-3.997 79.96-3.997h820.63c32.49 0 61.97 2 88.96 5.497M1348.84-41.084H2526.8m221.4-195.913V-850.22m989.55 614.723c26.49 3 49.98 7.996 71.47 14.493 93.96 28.49 140.93 88.462 140.93 179.92m2024.08 0h50.98m-468.28 0h219.89m-1826.67 0h1416.86M3737.75-235.497V-850.22m212.4 809.136H2526.8M3737.75-850.22H2748.2" fill="none" stroke="#161616" stroke-width="79.964" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
<path d="M2126.79-2789.58c-38.13 38.49-57.37 85.01-57.37 139.59 0 54.22 19.24 100.75 57.37 139.23 38.48 38.48 85.01 57.73 139.59 57.73 54.22 0 100.75-19.25 139.23-57.73 38.49-38.48 57.73-85.01 57.73-139.23 0-54.58-19.24-101.1-57.73-139.59-38.48-38.13-85.01-57.37-139.23-57.37-54.58 0-101.11 19.24-139.59 57.37z" fill="none" stroke="#161616" stroke-width="69.967" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
<path d="M2640.7-3448.32c-286.51-11.2-546.09 38.83-778.73 150.43 143.08-106.7 307.5-172.47 493.27-197.66-6.3-14.34-18.9-29.04-38.13-43.73h-62.98c-210.25 36.73-380.62 103.9-511.11 201.16-197.66 325.7-291.76 678.68-281.62 1058.6 142.39 189.97 349.49 279.53 621.31 267.98l122.45-129.44c-148.68-52.82-255.03-123.49-318.7-212 214.1 133.99 465.63 199.41 754.24 196.26" fill="none" stroke="#161616" stroke-width="69.967" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
<path d="M-3149.74-2789.58c-38.13 38.49-57.37 85.01-57.37 139.59 0 54.22 19.24 100.75 57.37 139.23 38.49 38.48 85.01 57.73 139.59 57.73 54.22 0 100.75-19.25 139.23-57.73 38.49-38.48 57.73-85.01 57.73-139.23 0-54.58-19.24-101.1-57.73-139.59-38.48-38.13-85.01-57.37-139.23-57.37-54.58 0-101.1 19.24-139.59 57.37z" fill="none" stroke="#161616" stroke-width="69.967" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(-.13334 0 0 .13333 0 597.333)"/>
<path d="M-2635.83-3448.32c-286.51-11.2-546.09 38.83-778.73 150.43 143.08-106.7 307.5-172.47 493.27-197.66-6.3-14.34-18.89-29.04-38.13-43.73h-62.98c-210.25 36.73-380.62 103.9-511.11 201.16-197.66 325.7-291.76 678.68-281.62 1058.6 142.39 189.97 349.49 279.53 621.32 267.98l122.44-129.44c-148.68-52.82-255.03-123.49-318.7-212 214.1 133.99 465.63 199.41 754.24 196.26" fill="none" stroke="#161616" stroke-width="69.967" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(-.13334 0 0 .13333 0 597.333)"/>
<path d="M474.47 230.785c-17.793 0-26.655 8.863-26.655 26.654v261.2-23.99H207.912h47.98v-58.9 34.91h143.94-47.98v23.99h95.963v-94.88c-.534-16.73-9.396-25.06-26.656-25.06H186.58c-17.792 0-26.656 8.86-26.656 26.65v163.85c0 17.26 8.33 26.12 25.057 26.65h333.8c16.66-.53 24.99-9.39 24.99-26.65V326.74h-34.65c-16.66.667-24.65-7.33-23.99-23.987h300.28c4.2-7.13 6.27-15.126 6.27-23.99v-21.32c0-17.792-8.86-26.655-26.65-26.655zm-13.327 311.842l23.99 22.588-23.99-22.588" fill="#376fa1"/>
<path d="M777.616 312.677c3.132-3.132 5.73-6.397 7.796-9.928h-300.28c-.665 16.65 7.33 24.65 23.992 23.98h234.572c13.26 0 24.523-4.67 33.92-14.06" fill="#578fc1"/>
<path d="M3890.68-40.99H1387.32m1971.1-1440.85v-1067.51c0-133.44 66.47-199.91 199.91-199.91h2179.01c133.44 0 199.91 66.47 199.91 199.91v159.93c0 66.47-15.49 126.44-46.98 179.92" fill="none" stroke="#000" stroke-width="79.964" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
<path d="M5890.27-2209.5c-15.49 26.48-34.98 50.97-58.47 74.46-70.47 70.47-154.93 105.45-254.39 105.45H4078.1M3358.42-590.243V-770.16m719.68-1259.43h-259.88m-459.8 1259.43v-711.68M3638.3-240.9l-179.92-169.423M4449.93-40.99h-559.25m187.42-1988.6V-240.9c0 129.44-62.48 195.91-187.42 199.91m1007.04 0H4717.8M1559.24-770.16h359.84m4777.83-1259.43l-179.92-179.91m0 0l179.92-179.92M949.022-40.99h438.298M6516.99-2209.5h-626.72m-3971.19 997.54v261.88m0 0v179.92m1079.51-179.92h-359.84m0 0v179.92m-719.67-179.92h719.67m0 179.92h-719.67M1387.32-40.99c-125.44-4-187.91-70.47-187.91-199.91v-1228.94c0-133.44 66.47-199.91 199.9-199.91h1759.2c129.45 0 195.92 62.47 199.91 187.91m-719.67 711.68h719.67" fill="none" stroke="#000" stroke-width="79.964" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
<path d="M7716.44-2209.5H7356.6m0 539.75l-179.92-179.92m179.92-899.59l-179.92 179.92" fill="none" stroke="#161616" stroke-width="99.954" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" transform="matrix(.13334 0 0 .13333 0 597.333)"/>
<path d="M769.485 258.24c-2.332-2.333-5.13-3.467-8.462-3.467s-6.198 1.134-8.53 3.466c-2.333 2.33-3.466 5.19-3.466 8.52s1.133 6.13 3.466 8.46c2.332 2.33 5.198 3.53 8.53 3.53 3.332 0 6.13-1.2 8.462-3.53 2.334-2.34 3.532-5.13 3.532-8.47 0-3.33-1.198-6.2-3.532-8.53"/>
</svg>

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -6,7 +6,8 @@
Welcome to discord.py
===========================
.. image:: /images/snake.png
.. image:: /images/snake.svg
.. image:: /images/snake_dark.svg
discord.py is a modern, easy to use, feature-rich, and async ready API wrapper
for Discord.

View File

@ -36,8 +36,8 @@ with open('README.rst') as f:
extras_require = {
'voice': ['PyNaCl==1.3.0'],
'docs': [
'sphinx==1.8.5',
'sphinxcontrib_trio==1.1.1',
'sphinx==3.0.3',
'sphinxcontrib_trio==1.1.2',
'sphinxcontrib-websupport',
]
}