mkdocs-zip-bundle-plugin 0.1.1__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mkdocs_zip_bundle_plugin-0.1.1 → mkdocs_zip_bundle_plugin-0.2.0}/PKG-INFO +7 -5
- {mkdocs_zip_bundle_plugin-0.1.1 → mkdocs_zip_bundle_plugin-0.2.0}/README.md +4 -2
- mkdocs_zip_bundle_plugin-0.2.0/mkdocs_zip_bundle/assets/zip-bundle.js +157 -0
- {mkdocs_zip_bundle_plugin-0.1.1 → mkdocs_zip_bundle_plugin-0.2.0}/mkdocs_zip_bundle_plugin.egg-info/PKG-INFO +7 -5
- {mkdocs_zip_bundle_plugin-0.1.1 → mkdocs_zip_bundle_plugin-0.2.0}/pyproject.toml +6 -3
- mkdocs_zip_bundle_plugin-0.1.1/mkdocs_zip_bundle/assets/zip-bundle.js +0 -67
- {mkdocs_zip_bundle_plugin-0.1.1 → mkdocs_zip_bundle_plugin-0.2.0}/LICENSE +0 -0
- {mkdocs_zip_bundle_plugin-0.1.1 → mkdocs_zip_bundle_plugin-0.2.0}/mkdocs_zip_bundle/__init__.py +0 -0
- {mkdocs_zip_bundle_plugin-0.1.1 → mkdocs_zip_bundle_plugin-0.2.0}/mkdocs_zip_bundle/assets/jszip.min.js +0 -0
- {mkdocs_zip_bundle_plugin-0.1.1 → mkdocs_zip_bundle_plugin-0.2.0}/mkdocs_zip_bundle/assets/zip-bundle.css +0 -0
- {mkdocs_zip_bundle_plugin-0.1.1 → mkdocs_zip_bundle_plugin-0.2.0}/mkdocs_zip_bundle/plugin.py +0 -0
- {mkdocs_zip_bundle_plugin-0.1.1 → mkdocs_zip_bundle_plugin-0.2.0}/mkdocs_zip_bundle_plugin.egg-info/SOURCES.txt +0 -0
- {mkdocs_zip_bundle_plugin-0.1.1 → mkdocs_zip_bundle_plugin-0.2.0}/mkdocs_zip_bundle_plugin.egg-info/dependency_links.txt +0 -0
- {mkdocs_zip_bundle_plugin-0.1.1 → mkdocs_zip_bundle_plugin-0.2.0}/mkdocs_zip_bundle_plugin.egg-info/entry_points.txt +0 -0
- {mkdocs_zip_bundle_plugin-0.1.1 → mkdocs_zip_bundle_plugin-0.2.0}/mkdocs_zip_bundle_plugin.egg-info/requires.txt +0 -0
- {mkdocs_zip_bundle_plugin-0.1.1 → mkdocs_zip_bundle_plugin-0.2.0}/mkdocs_zip_bundle_plugin.egg-info/top_level.txt +0 -0
- {mkdocs_zip_bundle_plugin-0.1.1 → mkdocs_zip_bundle_plugin-0.2.0}/setup.cfg +0 -0
- {mkdocs_zip_bundle_plugin-0.1.1 → mkdocs_zip_bundle_plugin-0.2.0}/tests/test_integration.py +0 -0
- {mkdocs_zip_bundle_plugin-0.1.1 → mkdocs_zip_bundle_plugin-0.2.0}/tests/test_plugin.py +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mkdocs-zip-bundle-plugin
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Bundle code blocks into downloadable ZIP or raw files — for MkDocs/Material and Zensical.
|
|
5
5
|
Author: Daemonless
|
|
6
6
|
License: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/daemonless/mkdocs-zip-bundle-plugin
|
|
8
8
|
Project-URL: Repository, https://github.com/daemonless/mkdocs-zip-bundle-plugin
|
|
9
9
|
Project-URL: Bug Tracker, https://github.com/daemonless/mkdocs-zip-bundle-plugin/issues
|
|
10
|
-
Keywords: mkdocs,zip,bundle,placeholders,interactive
|
|
10
|
+
Keywords: mkdocs,material,zensical,zip,bundle,placeholders,interactive
|
|
11
11
|
Requires-Python: >=3.8
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
License-File: LICENSE
|
|
@@ -17,9 +17,11 @@ Dynamic: license-file
|
|
|
17
17
|
|
|
18
18
|
# mkdocs-zip-bundle-plugin
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Turn code blocks into downloadable files — for **MkDocs/Material** and **[Zensical](https://zensical.org)**. Tag any code block with a bundle ID and filename and a download button is injected automatically. Works with single files (direct download) or multiple files (ZIP archive).
|
|
21
21
|
|
|
22
|
-
Built to pair with [`mkdocs-placeholder-plugin`](https://github.com/six-two/mkdocs-placeholder-plugin): if your docs use interactive placeholders like `@PORT@`, the downloaded file will contain the user's actual values, not the defaults.
|
|
22
|
+
Built to pair with [`mkdocs-placeholder-plugin`](https://github.com/six-two/mkdocs-placeholder-plugin): if your docs use interactive placeholders like `@PORT@`, the downloaded file will contain the user's actual values, not the defaults. _(MkDocs/Material — see [Using with Zensical](https://mkdocs-zip-bundle-plugin.daemonless.io/configuration/#using-with-zensical) for the Zensical caveat.)_
|
|
23
|
+
|
|
24
|
+
**[Live demo → mkdocs-zip-bundle-plugin.daemonless.io](https://mkdocs-zip-bundle-plugin.daemonless.io)**
|
|
23
25
|
|
|
24
26
|
## Features
|
|
25
27
|
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# mkdocs-zip-bundle-plugin
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Turn code blocks into downloadable files — for **MkDocs/Material** and **[Zensical](https://zensical.org)**. Tag any code block with a bundle ID and filename and a download button is injected automatically. Works with single files (direct download) or multiple files (ZIP archive).
|
|
4
4
|
|
|
5
|
-
Built to pair with [`mkdocs-placeholder-plugin`](https://github.com/six-two/mkdocs-placeholder-plugin): if your docs use interactive placeholders like `@PORT@`, the downloaded file will contain the user's actual values, not the defaults.
|
|
5
|
+
Built to pair with [`mkdocs-placeholder-plugin`](https://github.com/six-two/mkdocs-placeholder-plugin): if your docs use interactive placeholders like `@PORT@`, the downloaded file will contain the user's actual values, not the defaults. _(MkDocs/Material — see [Using with Zensical](https://mkdocs-zip-bundle-plugin.daemonless.io/configuration/#using-with-zensical) for the Zensical caveat.)_
|
|
6
|
+
|
|
7
|
+
**[Live demo → mkdocs-zip-bundle-plugin.daemonless.io](https://mkdocs-zip-bundle-plugin.daemonless.io)**
|
|
6
8
|
|
|
7
9
|
## Features
|
|
8
10
|
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
// ── Button injection ──────────────────────────────────────────────────
|
|
2
|
+
// Mirrors the Python plugin's on_page_content / _create_button so the
|
|
3
|
+
// download buttons exist even where the plugin's build hook never runs
|
|
4
|
+
// (e.g. Zensical). Idempotent: skips any bundle that already has a button,
|
|
5
|
+
// so on MkDocs/Material (server-injected) this is a harmless no-op.
|
|
6
|
+
|
|
7
|
+
function sanitizeFilename(filename) {
|
|
8
|
+
// Match plugin._sanitize_filename: prevent path traversal, allow subdirs.
|
|
9
|
+
filename = filename.replace(/\\/g, '/'); // backslashes -> forward
|
|
10
|
+
filename = filename.replace(/\.\.(?=\/|$)/g, ''); // drop ".." segments
|
|
11
|
+
filename = filename.replace(/^\/+/, ''); // no leading slashes
|
|
12
|
+
filename = filename.replace(/\/+/g, '/'); // collapse slashes
|
|
13
|
+
return filename.trim();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function titleCase(str) {
|
|
17
|
+
// Python str.title(): capitalize each word, lowercase the rest.
|
|
18
|
+
return str.replace(/\w\S*/g, t => t.charAt(0).toUpperCase() + t.slice(1).toLowerCase());
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function buildButtonContainer(bundleId, elements) {
|
|
22
|
+
const cfg = window.zipBundleConfig || {};
|
|
23
|
+
const labelSuffix = cfg.labelSuffix || '(.zip)';
|
|
24
|
+
|
|
25
|
+
const btn = document.createElement('button');
|
|
26
|
+
btn.className = 'md-button zip-bundle-btn';
|
|
27
|
+
btn.setAttribute('data-bundle-id', bundleId);
|
|
28
|
+
btn.type = 'button';
|
|
29
|
+
btn.setAttribute('aria-label', `Download ${bundleId.replace(/-/g, ' ')} bundle`);
|
|
30
|
+
|
|
31
|
+
const customLabel = elements
|
|
32
|
+
.map(el => el.getAttribute('data-zip-label'))
|
|
33
|
+
.find(Boolean);
|
|
34
|
+
const forceZip = elements.some(el => el.getAttribute('data-zip-force') === 'true');
|
|
35
|
+
|
|
36
|
+
if (customLabel) {
|
|
37
|
+
btn.textContent = customLabel;
|
|
38
|
+
} else if (elements.length === 1 && !forceZip) {
|
|
39
|
+
const filename = elements[0].getAttribute('data-zip-filename') || 'file';
|
|
40
|
+
const displayName = filename.split('/').pop(); // basename
|
|
41
|
+
btn.textContent = `Download ${displayName}`;
|
|
42
|
+
} else {
|
|
43
|
+
const label = titleCase(bundleId.replace(/-/g, ' '));
|
|
44
|
+
btn.textContent = `Download ${label} ${labelSuffix}`.trim();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const container = document.createElement('div');
|
|
48
|
+
container.className = 'zip-bundle-container';
|
|
49
|
+
container.appendChild(btn);
|
|
50
|
+
return container;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function injectZipButtons() {
|
|
54
|
+
const tagged = document.querySelectorAll('[data-zip-bundle]');
|
|
55
|
+
if (tagged.length === 0) return;
|
|
56
|
+
|
|
57
|
+
// Group elements by bundle id, preserving document order.
|
|
58
|
+
const bundles = new Map();
|
|
59
|
+
tagged.forEach(el => {
|
|
60
|
+
if (el.hasAttribute('data-zip-filename')) {
|
|
61
|
+
el.setAttribute('data-zip-filename',
|
|
62
|
+
sanitizeFilename(el.getAttribute('data-zip-filename')));
|
|
63
|
+
}
|
|
64
|
+
const id = el.getAttribute('data-zip-bundle');
|
|
65
|
+
if (!bundles.has(id)) bundles.set(id, []);
|
|
66
|
+
bundles.get(id).push(el);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
bundles.forEach((elements, id) => {
|
|
70
|
+
// Idempotent: skip if a button already exists (server-injected or a
|
|
71
|
+
// prior run under instant navigation).
|
|
72
|
+
const sel = `.zip-bundle-btn[data-bundle-id="${CSS.escape(id)}"]`;
|
|
73
|
+
if (document.querySelector(sel)) return;
|
|
74
|
+
const container = buildButtonContainer(id, elements);
|
|
75
|
+
elements[elements.length - 1].insertAdjacentElement('afterend', container);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Run on initial load and on every (instant) navigation. Material/Zensical
|
|
80
|
+
// expose the document$ observable; fall back to DOMContentLoaded elsewhere.
|
|
81
|
+
if (window.document$ && typeof window.document$.subscribe === 'function') {
|
|
82
|
+
window.document$.subscribe(injectZipButtons);
|
|
83
|
+
} else if (document.readyState !== 'loading') {
|
|
84
|
+
injectZipButtons();
|
|
85
|
+
} else {
|
|
86
|
+
document.addEventListener('DOMContentLoaded', injectZipButtons);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ── Download handling ─────────────────────────────────────────────────
|
|
90
|
+
|
|
91
|
+
document.addEventListener('click', function(e) {
|
|
92
|
+
const btn = e.target.closest('.zip-bundle-btn[data-bundle-id]');
|
|
93
|
+
if (btn) {
|
|
94
|
+
downloadZipBundle(btn.getAttribute('data-bundle-id'));
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
async function downloadZipBundle(bundleId) {
|
|
99
|
+
const elements = document.querySelectorAll(`[data-zip-bundle="${bundleId}"]`);
|
|
100
|
+
|
|
101
|
+
if (elements.length === 0) {
|
|
102
|
+
console.warn(`No elements found for bundle ID: ${bundleId}`);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const forceZip = Array.from(elements).some(el => el.getAttribute('data-zip-force') === 'true');
|
|
107
|
+
|
|
108
|
+
// If it's only one file AND we aren't forcing a ZIP, download it directly
|
|
109
|
+
if (elements.length === 1 && !forceZip) {
|
|
110
|
+
const el = elements[0];
|
|
111
|
+
const filename = el.getAttribute('data-zip-filename') || 'file';
|
|
112
|
+
const codeEl = el.querySelector('code') || el;
|
|
113
|
+
const content = codeEl.innerText;
|
|
114
|
+
|
|
115
|
+
// Ensure UTF-8 encoding
|
|
116
|
+
const blob = new Blob([content], { type: "text/plain;charset=utf-8" });
|
|
117
|
+
const url = URL.createObjectURL(blob);
|
|
118
|
+
triggerDownload(url, filename);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Multiple files (or forced single ZIP)
|
|
123
|
+
if (typeof JSZip === 'undefined') {
|
|
124
|
+
console.error('JSZip is not loaded. Please include it in your mkdocs.yml extra_javascript or enable it in the plugin config.');
|
|
125
|
+
alert('Error: ZIP library not loaded.');
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const zip = new JSZip();
|
|
130
|
+
elements.forEach(el => {
|
|
131
|
+
const filename = el.getAttribute('data-zip-filename') || 'unnamed-file';
|
|
132
|
+
const codeEl = el.querySelector('code') || el;
|
|
133
|
+
const content = codeEl.innerText;
|
|
134
|
+
|
|
135
|
+
// Skip empty files if they have no content
|
|
136
|
+
if (content.trim().length === 0) {
|
|
137
|
+
console.warn(`Skipping empty file: ${filename}`);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
zip.file(filename, content);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
const blob = await zip.generateAsync({type: "blob"});
|
|
145
|
+
const url = URL.createObjectURL(blob);
|
|
146
|
+
triggerDownload(url, `${bundleId}.zip`);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function triggerDownload(url, filename) {
|
|
150
|
+
const a = document.createElement('a');
|
|
151
|
+
a.href = url;
|
|
152
|
+
a.download = filename;
|
|
153
|
+
document.body.appendChild(a);
|
|
154
|
+
a.click();
|
|
155
|
+
document.body.removeChild(a);
|
|
156
|
+
URL.revokeObjectURL(url);
|
|
157
|
+
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mkdocs-zip-bundle-plugin
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Bundle code blocks into downloadable ZIP or raw files — for MkDocs/Material and Zensical.
|
|
5
5
|
Author: Daemonless
|
|
6
6
|
License: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/daemonless/mkdocs-zip-bundle-plugin
|
|
8
8
|
Project-URL: Repository, https://github.com/daemonless/mkdocs-zip-bundle-plugin
|
|
9
9
|
Project-URL: Bug Tracker, https://github.com/daemonless/mkdocs-zip-bundle-plugin/issues
|
|
10
|
-
Keywords: mkdocs,zip,bundle,placeholders,interactive
|
|
10
|
+
Keywords: mkdocs,material,zensical,zip,bundle,placeholders,interactive
|
|
11
11
|
Requires-Python: >=3.8
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
License-File: LICENSE
|
|
@@ -17,9 +17,11 @@ Dynamic: license-file
|
|
|
17
17
|
|
|
18
18
|
# mkdocs-zip-bundle-plugin
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Turn code blocks into downloadable files — for **MkDocs/Material** and **[Zensical](https://zensical.org)**. Tag any code block with a bundle ID and filename and a download button is injected automatically. Works with single files (direct download) or multiple files (ZIP archive).
|
|
21
21
|
|
|
22
|
-
Built to pair with [`mkdocs-placeholder-plugin`](https://github.com/six-two/mkdocs-placeholder-plugin): if your docs use interactive placeholders like `@PORT@`, the downloaded file will contain the user's actual values, not the defaults.
|
|
22
|
+
Built to pair with [`mkdocs-placeholder-plugin`](https://github.com/six-two/mkdocs-placeholder-plugin): if your docs use interactive placeholders like `@PORT@`, the downloaded file will contain the user's actual values, not the defaults. _(MkDocs/Material — see [Using with Zensical](https://mkdocs-zip-bundle-plugin.daemonless.io/configuration/#using-with-zensical) for the Zensical caveat.)_
|
|
23
|
+
|
|
24
|
+
**[Live demo → mkdocs-zip-bundle-plugin.daemonless.io](https://mkdocs-zip-bundle-plugin.daemonless.io)**
|
|
23
25
|
|
|
24
26
|
## Features
|
|
25
27
|
|
|
@@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "mkdocs-zip-bundle-plugin"
|
|
7
|
-
version = "0.
|
|
8
|
-
description = "
|
|
7
|
+
version = "0.2.0"
|
|
8
|
+
description = "Bundle code blocks into downloadable ZIP or raw files — for MkDocs/Material and Zensical."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [{ name = "Daemonless" }]
|
|
11
11
|
license = { text = "MIT" }
|
|
12
12
|
requires-python = ">=3.8"
|
|
13
|
-
keywords = ["mkdocs", "zip", "bundle", "placeholders", "interactive"]
|
|
13
|
+
keywords = ["mkdocs", "material", "zensical", "zip", "bundle", "placeholders", "interactive"]
|
|
14
14
|
dependencies = [
|
|
15
15
|
"mkdocs>=1.4.0",
|
|
16
16
|
"beautifulsoup4>=4.11.0"
|
|
@@ -24,5 +24,8 @@ Repository = "https://github.com/daemonless/mkdocs-zip-bundle-plugin"
|
|
|
24
24
|
[project.entry-points."mkdocs.plugins"]
|
|
25
25
|
zip-bundle = "mkdocs_zip_bundle.plugin:ZipBundlePlugin"
|
|
26
26
|
|
|
27
|
+
[tool.setuptools.packages.find]
|
|
28
|
+
include = ["mkdocs_zip_bundle*"]
|
|
29
|
+
|
|
27
30
|
[tool.setuptools.package-data]
|
|
28
31
|
mkdocs_zip_bundle = ["assets/*"]
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
document.addEventListener('click', function(e) {
|
|
2
|
-
const btn = e.target.closest('.zip-bundle-btn[data-bundle-id]');
|
|
3
|
-
if (btn) {
|
|
4
|
-
downloadZipBundle(btn.getAttribute('data-bundle-id'));
|
|
5
|
-
}
|
|
6
|
-
});
|
|
7
|
-
|
|
8
|
-
async function downloadZipBundle(bundleId) {
|
|
9
|
-
const elements = document.querySelectorAll(`[data-zip-bundle="${bundleId}"]`);
|
|
10
|
-
|
|
11
|
-
if (elements.length === 0) {
|
|
12
|
-
console.warn(`No elements found for bundle ID: ${bundleId}`);
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const forceZip = Array.from(elements).some(el => el.getAttribute('data-zip-force') === 'true');
|
|
17
|
-
|
|
18
|
-
// If it's only one file AND we aren't forcing a ZIP, download it directly
|
|
19
|
-
if (elements.length === 1 && !forceZip) {
|
|
20
|
-
const el = elements[0];
|
|
21
|
-
const filename = el.getAttribute('data-zip-filename') || 'file';
|
|
22
|
-
const codeEl = el.querySelector('code') || el;
|
|
23
|
-
const content = codeEl.innerText;
|
|
24
|
-
|
|
25
|
-
// Ensure UTF-8 encoding
|
|
26
|
-
const blob = new Blob([content], { type: "text/plain;charset=utf-8" });
|
|
27
|
-
const url = URL.createObjectURL(blob);
|
|
28
|
-
triggerDownload(url, filename);
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Multiple files (or forced single ZIP)
|
|
33
|
-
if (typeof JSZip === 'undefined') {
|
|
34
|
-
console.error('JSZip is not loaded. Please include it in your mkdocs.yml extra_javascript or enable it in the plugin config.');
|
|
35
|
-
alert('Error: ZIP library not loaded.');
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const zip = new JSZip();
|
|
40
|
-
elements.forEach(el => {
|
|
41
|
-
const filename = el.getAttribute('data-zip-filename') || 'unnamed-file';
|
|
42
|
-
const codeEl = el.querySelector('code') || el;
|
|
43
|
-
const content = codeEl.innerText;
|
|
44
|
-
|
|
45
|
-
// Skip empty files if they have no content
|
|
46
|
-
if (content.trim().length === 0) {
|
|
47
|
-
console.warn(`Skipping empty file: ${filename}`);
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
zip.file(filename, content);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
const blob = await zip.generateAsync({type: "blob"});
|
|
55
|
-
const url = URL.createObjectURL(blob);
|
|
56
|
-
triggerDownload(url, `${bundleId}.zip`);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function triggerDownload(url, filename) {
|
|
60
|
-
const a = document.createElement('a');
|
|
61
|
-
a.href = url;
|
|
62
|
-
a.download = filename;
|
|
63
|
-
document.body.appendChild(a);
|
|
64
|
-
a.click();
|
|
65
|
-
document.body.removeChild(a);
|
|
66
|
-
URL.revokeObjectURL(url);
|
|
67
|
-
}
|
|
File without changes
|
{mkdocs_zip_bundle_plugin-0.1.1 → mkdocs_zip_bundle_plugin-0.2.0}/mkdocs_zip_bundle/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mkdocs_zip_bundle_plugin-0.1.1 → mkdocs_zip_bundle_plugin-0.2.0}/mkdocs_zip_bundle/plugin.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|