Skip to content

Commit 4e419ed

Browse files
authored
Merge pull request #9 from neatc0der/release/v1.0
Release/v1.0
2 parents 3d376f6 + 6a4db73 commit 4e419ed

File tree

13 files changed

+168
-73
lines changed

13 files changed

+168
-73
lines changed

.build/mkdocs_markmap_build/common.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,14 @@ def get_assets_from_release(self) -> List[str]:
9595

9696

9797
class ChangelogLoader:
98-
def __init__(self, changelog_path: Path = CHANGELOG_PATH) -> None:
99-
self._changelog_path = changelog_path
98+
def __init__(self, tag: str, changelog_path: Path = CHANGELOG_PATH) -> None:
99+
self.tag = tag
100+
self._path = changelog_path / f'{self.tag}.md'
100101

102+
@property
103+
def path(self) -> Path:
104+
return self._path
105+
101106
def _drop_headline(self, content: str) -> str:
102107
headline_detected: bool = False
103108
text_started: bool = False
@@ -122,9 +127,9 @@ def _drop_headline(self, content: str) -> str:
122127

123128
return '\n'.join(lines)
124129

125-
def get(self, release: str, drop_headline: bool = True) -> str:
130+
def get(self, drop_headline: bool = True) -> str:
126131
try:
127-
with open(self._changelog_path / f'{release}.md', 'r') as fp:
132+
with open(self._path, 'r') as fp:
128133
content = fp.read()
129134

130135
if drop_headline:
@@ -133,5 +138,5 @@ def get(self, release: str, drop_headline: bool = True) -> str:
133138
return content
134139

135140
except OSError as e:
136-
print(f'unable to load changelog for release {release}: {e}')
141+
print(f'unable to load changelog for release {self.tag}: {e}')
137142
sys.exit(1)

.build/mkdocs_markmap_build/release.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import sys
22
from pprint import pprint
33
from typing import Dict, List
4+
from time import sleep
5+
46
from github.Commit import Commit
57
from github.GitAuthor import GitAuthor
68
from github.GitCommit import GitCommit
7-
89
from github.GitRelease import GitRelease
910
from github.GitReleaseAsset import GitReleaseAsset
1011
from github.InputGitAuthor import InputGitAuthor
@@ -18,11 +19,11 @@
1819
class ReleaseHandler(GithubHandler):
1920
def __init__(self, tag: str) -> None:
2021
super(ReleaseHandler, self).__init__(tag)
21-
self._changelog = ChangelogLoader()
22+
self._changelog = ChangelogLoader(tag)
2223
self._collector = AssetCollector()
2324

2425
def create(self, commit: str = None, dry_run: bool = True):
25-
release_message: str = self._changelog.get(self.tag)
26+
release_message: str = self._changelog.get()
2627
assets: List[str] = self._collector.get_assets()
2728
tagger: GitAuthor = None
2829

@@ -50,7 +51,6 @@ def create(self, commit: str = None, dry_run: bool = True):
5051
f'tag "{self.tag}" already exists'
5152
assert self.tag not in (release.tag_name for release in self.repository.get_releases()), \
5253
f'release "{self.tag}" already exists'
53-
5454
except AssertionError as e:
5555
print(e)
5656
sys.exit(1)
@@ -66,6 +66,10 @@ def create(self, commit: str = None, dry_run: bool = True):
6666
release_asset: GitReleaseAsset = release.upload_asset(asset)
6767
print(f'Release asset "{release_asset.name}" uploaded: {release_asset.url}')
6868

69+
# Give github some time to sort things out with the new release.
70+
# Otherwise the "published" event will not be triggered.
71+
sleep(5)
72+
6973
release = release.update_release(
7074
name=self.tag,
7175
message=release_message,
@@ -76,20 +80,16 @@ def create(self, commit: str = None, dry_run: bool = True):
7680
def delete(self):
7781
try:
7882
next(t for t in self.repository.get_tags() if t.name == self.tag)
79-
8083
except StopIteration:
8184
print(f'Tag "{self.tag}" does not exist')
82-
8385
else:
8486
self.repository.get_git_ref(f'tags/{self.tag}').delete()
8587
print(f'Tag "{self.tag}" deleted')
8688

8789
try:
8890
release: GitRelease = next(r for r in self.repository.get_releases() if r.tag_name == self.tag)
89-
9091
except StopIteration:
9192
print(f'Release "{self.tag}" does not exist')
92-
9393
else:
9494
release.delete_release()
9595
print(f'Release "{self.tag}" deleted')

.github/workflows/verify.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Verification Workflow
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- master
7+
8+
jobs:
9+
build:
10+
name: Distribute
11+
runs-on: ubuntu-latest
12+
steps:
13+
- name: Checkout code
14+
uses: actions/checkout@v2
15+
16+
- name: Prepare Python
17+
uses: actions/setup-python@v2
18+
with:
19+
python-version: 3.8
20+
21+
- name: Install Dependencies
22+
run: |
23+
python3 -m pip install --upgrade pip
24+
pip install -r requirements/build.txt
25+
python3 setup.py install
26+
27+
- name: Verify Integrity
28+
run: inv verify

README.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# mkdocs-markmap
22

3+
> Beautiful and simple mindmaps written in markdown.
4+
35
This is a plugin and an extension for [mkdocs](https://github.com/mkdocs/mkdocs/) to add [markmap](https://github.com/gera2ld/markmap).
46

57
## Prerequisits
@@ -9,7 +11,7 @@ This plugin was tested with, but is not limited to:
911
* Python 3.8
1012
* mkdocs 1.1
1113

12-
## How to integrate this?
14+
## Quickstart
1315

1416
### Install
1517

@@ -21,6 +23,17 @@ pip install mkdocs-markmap
2123

2224
Add this to `mkdocs.yml`:
2325

26+
```yaml
27+
markdown_extensions:
28+
- markmap:
29+
plugins:
30+
- markmap:
31+
```
32+
33+
## Advanced Settings
34+
35+
There are more options available for `mkdocs.yml` (shown values are defaults):
36+
2437
```yaml
2538
markdown_extensions:
2639
- markmap:
@@ -43,7 +56,7 @@ extra_javascript:
4356
- https://unpkg.com/[email protected]/dist/index.min.js
4457
```
4558

46-
:warning: The urls needs contain one of these keywords to be considered as deviation from default:
59+
:warning: The urls need to contain one of these keywords to be considered as deviation from default:
4760

4861
* `d3`
4962
* `markmap-lib`
@@ -81,7 +94,7 @@ Look at this beautiful mindmap:
8194
{!mindmap.mm.md!}
8295
```
8396

84-
But you _do_ need the plugin for that. Thus, don't forget to follow the setup example above.
97+
But you _do_ need the plugin for that. Thus, don't forget to follow the quickstart example above.
8598

8699
## Credits :clap:
87100

changelog/v1.0.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# v1.0
2+
3+
* Logger for all files
4+
* Javascript templates
5+
* Build workflow improvement
6+
* Readme update

mkdocs_markmap/__meta__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
PACKAGE_NAME = 'mkdocs_markmap'
22
PROJECT_NAME = PACKAGE_NAME.replace('_', '-')
3-
PROJECT_VERSION = '0.3'
3+
PROJECT_VERSION = '1.0'
44

55
OWNER = 'neatc0der'
66
REPOSITORY_NAME = f'{OWNER}/{PROJECT_NAME}'

mkdocs_markmap/extension.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
from pathlib import Path
1+
import logging
22
import re
3+
from pathlib import Path
34
from typing import AnyStr, Dict, List, Optional
45

56
from markdown import Markdown
67
from markdown.extensions import Extension
78
from markdown.preprocessors import Preprocessor
89

910

11+
log = logging.getLogger('mkdocs.markmap')
12+
13+
1014
INCLUDE_SYNTAX = re.compile(r'\{!\s*(?P<path>.+?)\s*!\}')
1115

1216

@@ -41,7 +45,7 @@ def run(self, lines: List[str]) -> List[str]:
4145
markmap: List[str] = r.readlines()
4246

4347
except Exception as e:
44-
print('Warning: could not include file {}. Ignoring statement. Error: {}'.format(path, e))
48+
log.error('unable to include file {}. Ignoring statement. Error: {}'.format(path, e))
4549
lines[loc] = INCLUDE_SYNTAX.sub('',line)
4650
break
4751

mkdocs_markmap/plugin.py

Lines changed: 39 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import logging
12
import re
23
from pathlib import Path
34
from typing import Dict, Tuple
@@ -7,44 +8,19 @@
78
from mkdocs.structure.pages import Page
89
from mkdocs.config.base import Config
910
from mkdocs.config.config_options import Type as PluginType
11+
from mkdocs.utils import copy_file
1012

1113
from .defaults import MARKMAP
1214
from .utils import download
1315

1416

15-
# todo: move this to template
16-
SCRIPT_CONTENT = """
17-
const markdown{index} = '{content}';
18-
const svg{index} = document.querySelector('#{tag_id}');
19-
const root{index} = markmap_transformer.transform(markdown{index}).root;
20-
var m{index} = markmap.Markmap.create(svg{index}, null, root{index});
21-
22-
m{index}.rescale(1).then(function() {{
23-
svg{index}.parentElement.style.height = (svg{index}.getBBox().height + 10) + "px";
24-
setTimeout(function() {{
25-
// todo: this is a dirty workaround to center the mindmap within svg
26-
while (svg{index}.firstChild) {{
27-
svg{index}.removeChild(svg{index}.lastChild);
28-
}}
29-
m{index} = markmap.Markmap.create(svg{index}, null, root{index});
30-
}}, 500);
31-
}});
32-
"""
33-
34-
# todo: move this to static file
35-
STYLE_CONTENT = """
36-
div.markmap {
37-
width: 100%;
38-
min-height: 1em;
39-
border: 1px solid grey;
40-
}
41-
.markmap > svg {
42-
width: 100%;
43-
height: 100%;
44-
}
45-
"""
17+
log = logging.getLogger('mkdocs.markmap')
4618

4719

20+
TEMPLATES_PATH: Path = Path(__file__).parent / 'templates'
21+
STYLE_PATH: Path = TEMPLATES_PATH / 'mkdocs-markmap.css'
22+
SCRIPT_PATH: Path = TEMPLATES_PATH / 'mkdocs-markmap.js'
23+
4824
class MarkmapPlugin(BasePlugin):
4925
"""
5026
Plugin for markmap support
@@ -78,42 +54,52 @@ def markmap(self) -> Dict[str, str]:
7854

7955
return self._markmap
8056

57+
def _load_scripts(self, soup: BeautifulSoup, script_base_url: str, js_path: Path) -> None:
58+
for script_url in self.markmap.values():
59+
try:
60+
src: str = script_base_url + download(js_path, script_url)
61+
except Exception as e:
62+
log.error(f'unable to download script: {script_url}')
63+
src = script_url
64+
65+
script: Tag = soup.new_tag('script', src=src, type='text/javascript')
66+
soup.head.append(script)
67+
68+
@staticmethod
69+
def _add_statics(soup: BeautifulSoup):
70+
statics = (
71+
(STYLE_PATH, 'style', 'text/css', 'head'),
72+
(SCRIPT_PATH, 'script', 'text/javascript', 'body'),
73+
)
74+
75+
for path, tag_name, text_type, attribute in statics:
76+
tag: Tag = soup.new_tag(tag_name, type=text_type)
77+
with open(path, 'r') as fp:
78+
tag.string = fp.read()
79+
getattr(soup, attribute).append(tag)
80+
8181
def on_post_page(self, output_content: str, config: Config, **kwargs) -> str:
8282
soup: BeautifulSoup = BeautifulSoup(output_content, 'html.parser')
8383
page: Page = kwargs.get('page')
8484

85-
script_base_url: str = re.sub(r'[^/]+?/', '../', re.sub(r'/+?', '/', page.url)) + 'js/'
86-
js_path: Path = Path(config['site_dir']) / 'js'
8785
markmaps: ResultSet = soup.find_all('code', class_='language-markmap')
88-
if any(markmaps):
89-
for script_url in self.markmap.values():
90-
src: str = script_base_url + download(js_path, script_url)
91-
script: Tag = soup.new_tag('script', src=src, type='text/javascript')
92-
soup.head.append(script)
93-
94-
style: Tag = soup.new_tag('style', type='text/css')
95-
style.string = STYLE_CONTENT
96-
soup.head.append(style)
86+
if not any(markmaps):
87+
return output_content
9788

98-
script: Tag = soup.new_tag('script')
99-
script.string = 'const markmap_transformer = new markmap.Transformer();'
100-
soup.head.append(script)
89+
script_base_url: str = re.sub(r'[^/]+?/', '../', re.sub(r'/+?', '/', page.url)) + 'js/'
90+
js_path: Path = Path(config['site_dir']) / 'js'
91+
self._load_scripts(soup, script_base_url, js_path)
92+
self._add_statics(soup)
10193

10294
for index, markmap in enumerate(markmaps):
10395
tag_id: str = f'markmap-{index}'
10496
markmap.parent.name = 'div'
105-
markmap.parent['class'] = markmap.parent.get('class', []) + ['markmap']
97+
markmap.parent['class'] = markmap.parent.get('class', []) + ['mkdocs-markmap']
98+
markmap.parent['data-markdown']=markmap.text.replace('\n', '&#10;')
10699
markmap.replaceWith(soup.new_tag(
107100
'svg',
108101
id=tag_id,
109102
attrs={'class': 'markmap'},
110103
))
111-
script: Tag = soup.new_tag('script')
112-
script.string = SCRIPT_CONTENT.format(
113-
index=index,
114-
tag_id=tag_id,
115-
content=markmap.text.replace('\n', '\\n'),
116-
)
117-
soup.body.append(script)
118104

119105
return str(soup)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
div.mkdocs-markmap {
2+
width: 100%;
3+
min-height: 1em;
4+
border: 1px solid grey;
5+
}
6+
.mkdocs-markmap > svg {
7+
width: 100%;
8+
height: 100%;
9+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
(function initializeMarkmap() {
2+
const markmap_transformer = new markmap.Transformer();
3+
const markmaps = document.getElementsByClassName('mkdocs-markmap');
4+
var el, content, svg, root, m;
5+
for (var i = 0; i < markmaps.length; i++) {
6+
el = markmaps[i];
7+
content = el.getAttribute('data-markdown').replaceAll('&#10;', '\n');
8+
svg = el.querySelector('svg');
9+
root = markmap_transformer.transform(content).root;
10+
m = markmap.Markmap.create(svg, null, root);
11+
12+
// todo: this is a dirty workaround to center the mindmap within svg
13+
(function(obj, e, r) {
14+
obj.rescale(1).then(function() {
15+
e.parentElement.style.height = (e.getBBox().height + 10) + "px";
16+
setTimeout(function() {
17+
while (e.firstChild) {
18+
e.removeChild(e.lastChild);
19+
}
20+
markmap.Markmap.create(e, null, r);
21+
}, 500);
22+
});
23+
})(m, svg, root);
24+
}
25+
})();

0 commit comments

Comments
 (0)