pystage 0.1.0.dev0__tar.gz → 0.1.2a1__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.
Files changed (100) hide show
  1. pystage-0.1.2a1/.gitignore +21 -0
  2. pystage-0.1.2a1/.readthedocs.yaml +20 -0
  3. pystage-0.1.2a1/CONTRIBUTING.md +26 -0
  4. pystage-0.1.2a1/MANIFEST.in +3 -0
  5. {pystage-0.1.0.dev0/src/pystage.egg-info → pystage-0.1.2a1}/PKG-INFO +9 -2
  6. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/README.md +7 -0
  7. pystage-0.1.2a1/block-images/.gitignore +3 -0
  8. pystage-0.1.2a1/block-images/cleanup.sh +7 -0
  9. pystage-0.1.2a1/block-images/crawl-images.md +250 -0
  10. pystage-0.1.2a1/block-images/export-png.sh +19 -0
  11. pystage-0.1.2a1/block-images/langs.json +73 -0
  12. pystage-0.1.2a1/docs/Makefile +20 -0
  13. pystage-0.1.2a1/docs/README.md +29 -0
  14. pystage-0.1.2a1/docs/build.bat +2 -0
  15. pystage-0.1.2a1/docs/make.bat +35 -0
  16. pystage-0.1.2a1/docs/pystage.png +0 -0
  17. pystage-0.1.2a1/docs/requirements.txt +6 -0
  18. pystage-0.1.2a1/docs/source/_templates/module.rst_t +8 -0
  19. pystage-0.1.2a1/docs/source/_templates/package.rst_t +51 -0
  20. pystage-0.1.2a1/docs/source/conf.py +148 -0
  21. pystage-0.1.2a1/docs/source/index.rst +31 -0
  22. pystage-0.1.2a1/docs/source/languages.rst +16 -0
  23. pystage-0.1.2a1/docs/source/logo.png +0 -0
  24. pystage-0.1.2a1/docs/source/modules.rst +7 -0
  25. pystage-0.1.2a1/docs/source/pystage.convert.rst +26 -0
  26. pystage-0.1.2a1/docs/source/pystage.core.rst +44 -0
  27. pystage-0.1.2a1/docs/source/pystage.de.rst +20 -0
  28. pystage-0.1.2a1/docs/source/pystage.en.rst +20 -0
  29. pystage-0.1.2a1/docs/source/pystage.rst +26 -0
  30. pystage-0.1.2a1/graphics/pen.svg +95 -0
  31. pystage-0.1.2a1/pytest.ini +6 -0
  32. pystage-0.1.2a1/requirements.txt +5 -0
  33. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/setup.cfg +4 -2
  34. pystage-0.1.2a1/src/example.py +71 -0
  35. pystage-0.1.2a1/src/example_bounce.py +20 -0
  36. pystage-0.1.2a1/src/example_de.py +22 -0
  37. pystage-0.1.2a1/src/example_en.py +15 -0
  38. pystage-0.1.2a1/src/example_en_ask.py +16 -0
  39. pystage-0.1.2a1/src/example_en_ghost.py +17 -0
  40. pystage-0.1.2a1/src/example_en_pen.py +16 -0
  41. pystage-0.1.2a1/src/example_en_turtle1.py +22 -0
  42. pystage-0.1.2a1/src/example_messages.py +20 -0
  43. pystage-0.1.2a1/src/example_monitors.py +32 -0
  44. pystage-0.1.2a1/src/example_positiontests.py +26 -0
  45. pystage-0.1.2a1/src/example_say.py +37 -0
  46. pystage-0.1.2a1/src/pystage/__init__.py +16 -0
  47. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/convert/sb3_templates.py +3 -1
  48. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/core/_base_sprite.py +2 -0
  49. pystage-0.1.2a1/src/pystage/core/_control.py +114 -0
  50. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/core/_events.py +2 -1
  51. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/core/_looks.py +3 -2
  52. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/core/_sensing.py +11 -2
  53. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/core/asking.py +5 -0
  54. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/core/assets.py +27 -15
  55. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/core/code_block.py +44 -1
  56. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/core/gui.py +18 -0
  57. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/core/sprite.py +2 -1
  58. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/core/stage.py +2 -0
  59. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/de/sprite.py +17 -3
  60. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/de/stage.py +2 -2
  61. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/en/sprite.py +24 -10
  62. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/en/stage.py +2 -2
  63. {pystage-0.1.0.dev0 → pystage-0.1.2a1/src/pystage.egg-info}/PKG-INFO +9 -2
  64. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage.egg-info/SOURCES.txt +42 -0
  65. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage.egg-info/requires.txt +1 -1
  66. pystage-0.1.0.dev0/src/pystage/__init__.py +0 -7
  67. pystage-0.1.0.dev0/src/pystage/core/_control.py +0 -54
  68. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/LICENSE +0 -0
  69. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/pyproject.toml +0 -0
  70. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/convert/__init__.py +0 -0
  71. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/convert/code_writer.py +0 -0
  72. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/convert/sb3.py +0 -0
  73. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/core/__init__.py +0 -0
  74. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/core/_motion.py +0 -0
  75. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/core/_operators.py +0 -0
  76. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/core/_pen.py +0 -0
  77. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/core/_sound.py +0 -0
  78. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/core/_variables.py +0 -0
  79. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/core/constants.py +0 -0
  80. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/core/messages.py +0 -0
  81. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/core/monitors.py +0 -0
  82. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/de/__init__.py +0 -0
  83. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/en/__init__.py +0 -0
  84. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/fonts/roboto-bold.ttf +0 -0
  85. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/fonts/roboto-light.ttf +0 -0
  86. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/fonts/roboto-regular.ttf +0 -0
  87. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/images/grid.svg +0 -0
  88. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/images/pen.png +0 -0
  89. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/images/say.png +0 -0
  90. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/images/think.png +0 -0
  91. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/images/zombie_idle.png +0 -0
  92. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/l10n/__init__.py +0 -0
  93. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/l10n/__main__.py +0 -0
  94. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/l10n/api.py +0 -0
  95. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/l10n/translations.py +0 -0
  96. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/sounds/dancehead2.wav +0 -0
  97. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/sounds/guitar.wav +0 -0
  98. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage/util.py +0 -0
  99. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage.egg-info/dependency_links.txt +0 -0
  100. {pystage-0.1.0.dev0 → pystage-0.1.2a1}/src/pystage.egg-info/top_level.txt +0 -0
@@ -0,0 +1,21 @@
1
+ dist/
2
+ build/
3
+ piptest/
4
+ .python-version
5
+ *.py[cod]
6
+ __pycache__/
7
+ *.egg-info
8
+ build.sh
9
+ .idea/
10
+ geckodriver.log
11
+ *.ipynb
12
+ .ipynb_checkpoints
13
+
14
+
15
+ # docs
16
+ /docs/source/_static
17
+ *.png
18
+ images/
19
+ sounds/
20
+
21
+ !tests/src/**
@@ -0,0 +1,20 @@
1
+ # .readthedocs.yaml
2
+ # Read the Docs configuration file
3
+ # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
4
+
5
+ # Required
6
+ version: 2
7
+
8
+ # Build documentation in the docs/ directory with Sphinx
9
+ sphinx:
10
+ configuration: docs/source/conf.py
11
+
12
+ # Optionally build your docs in additional formats such as PDF
13
+ # formats:
14
+ # - pdf
15
+
16
+ # Optionally set the version of Python and requirements required to build your docs
17
+ python:
18
+ # version: 3.7
19
+ install:
20
+ - requirements: docs/requirements.txt
@@ -0,0 +1,26 @@
1
+ # Contributing to PyStage
2
+
3
+
4
+ ## Making a Pull Request
5
+
6
+ - You can read here about how to usually [contribute to Open Source Projects](https://docs.github.com/en/get-started/quickstart/contributing-to-projects)
7
+ - We follow the [GitHub Flow](https://docs.github.com/en/get-started/quickstart/github-flow)
8
+
9
+ ### Outline of the process
10
+ - Make sure you have checked out the development branch and that you are on the most recent commit (do a `git pull` first).
11
+ - Then create a branch for your new feature or bug fix. If you work on several features, create a branch for each feature, all branching from development.
12
+ - Name your feature branch as meaningful as possible.
13
+ - While you work on your feature (until it finally gets merged into the official development branch), always keep your [feature branch in sync with the development branch](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/keeping-your-pull-request-in-sync-with-the-base-branch)
14
+
15
+ ### How to get your own working copy
16
+ - Fork the pystage repository to your own account
17
+ - Clone a working copy from your fork, as usual
18
+ - Add pystage as additional remote, usually called upstream: `git remote add upstream https://github.com/pystage/pystage.git`
19
+ - Switch to the development branch: `git checkout development`
20
+ - Create your new feature branch: `git checkout -b my-new-feature`
21
+ - Do your work...
22
+ - Push the feature branch to your forked repository
23
+ - Create a pull request via the GitHub website.
24
+ - If the development branch changes in upstream, fetch all changes from upstream and merge them into your feature branch:
25
+ - `git fetch upstream`
26
+ - `git merge upstream/development`
@@ -0,0 +1,3 @@
1
+ exclude tests/*
2
+ prune tests
3
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pystage
3
- Version: 0.1.0.dev0
3
+ Version: 0.1.2a1
4
4
  Summary: Scratch-like Python programming
5
5
  Home-page: https://github.com/pystage/pystage
6
6
  Author: Kai Eckert
@@ -15,7 +15,7 @@ Description-Content-Type: text/markdown
15
15
  License-File: LICENSE
16
16
  Requires-Dist: pygame
17
17
  Requires-Dist: jinja2
18
- Requires-Dist: svglib
18
+ Requires-Dist: setuptools
19
19
 
20
20
  # PyStage
21
21
 
@@ -139,6 +139,13 @@ Please note this is a pre alpha version. Not all things may work as expected. If
139
139
  ---
140
140
 
141
141
  # Import your Scratch projects
142
+
143
+ ## Use our Web converter
144
+ 1. Publish your Scratch project **or** download your Scratch project as .sb3 file.
145
+ 2. Go to https://convert.pystage.org and convert your project.
146
+ 3. Download the resulting zip file, it contains your new Python project ready to run.
147
+
148
+ ## Convert on your computer
142
149
  Converting a Scratch project to Python code:
143
150
  1. Export your Scratch project on the Scratch page. You will get an .sb3 file.
144
151
  2. Use our command line converter. Yes, it's unhandy, we will work on it to make things easier.
@@ -120,6 +120,13 @@ Please note this is a pre alpha version. Not all things may work as expected. If
120
120
  ---
121
121
 
122
122
  # Import your Scratch projects
123
+
124
+ ## Use our Web converter
125
+ 1. Publish your Scratch project **or** download your Scratch project as .sb3 file.
126
+ 2. Go to https://convert.pystage.org and convert your project.
127
+ 3. Download the resulting zip file, it contains your new Python project ready to run.
128
+
129
+ ## Convert on your computer
123
130
  Converting a Scratch project to Python code:
124
131
  1. Export your Scratch project on the Scratch page. You will get an .sb3 file.
125
132
  2. Use our command line converter. Yes, it's unhandy, we will work on it to make things easier.
@@ -0,0 +1,3 @@
1
+ svg/
2
+ icons/
3
+ allblocks.zip
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ # Crop all SVGs to their actual size
3
+ for i in $(find svg -name \*.svg)
4
+ do
5
+ echo $i
6
+ inkscape --export-area-drawing $i -o $i > /dev/null 2>&1
7
+ done
@@ -0,0 +1,250 @@
1
+ ---
2
+ jupyter:
3
+ jupytext:
4
+ formats: md,ipynb
5
+ text_representation:
6
+ extension: .md
7
+ format_name: markdown
8
+ format_version: '1.2'
9
+ jupytext_version: 1.7.1
10
+ kernelspec:
11
+ display_name: Python 3
12
+ language: python
13
+ name: python3
14
+ ---
15
+
16
+ ```python
17
+ from selenium import webdriver
18
+ from selenium.webdriver.common.keys import Keys
19
+ from selenium.webdriver.firefox.options import Options
20
+ from selenium.webdriver.support.ui import Select
21
+ from time import sleep
22
+ import requests
23
+ import os
24
+ import re
25
+ from IPython.display import SVG, display
26
+ import xml.etree.ElementTree as ET
27
+ import copy
28
+ from pathlib import Path
29
+ import json
30
+ import time
31
+ import base64
32
+
33
+ not_letters = re.compile(r"[^a-zA-Z0-9]")
34
+ namespaces = {"svg": "http://www.w3.org/2000/svg", "xlink": "http://www.w3.org/1999/xlink" }
35
+ # Scratch icons:
36
+ icons = ["repeat.svg", "dropdown-arrow.svg", "rotate-left.svg", "rotate-right.svg", "green-flag.svg"]
37
+
38
+ ```
39
+
40
+ ```python
41
+ def get_scratch_icons():
42
+ for i in icons:
43
+ data = requests.get(f"https://scratch.mit.edu/static/blocks-media/{i}").text
44
+ with open(f"icons/{i}", "w", encoding="utf-8") as f:
45
+ f.write(data)
46
+ ```
47
+
48
+ ```python
49
+ def start_selenium():
50
+ options = Options()
51
+ #options.add_argument('--headless')
52
+ # use to set language via browser
53
+ profile = webdriver.FirefoxProfile()
54
+ #profile.set_preference('intl.accept_languages', "de")
55
+ driver = webdriver.Firefox(options=options, firefox_profile=profile)
56
+ driver.set_window_size(1024, 768)
57
+ driver.get("https://scratch.mit.edu/projects/editor/")
58
+ time.sleep(3)
59
+ return driver
60
+
61
+ ```
62
+
63
+ ```python
64
+ def switch_language(driver: webdriver.Firefox, language: str):
65
+ select : Select = Select(driver.find_element_by_css_selector(".language-selector_language-select_8Vfnm"))
66
+ select.select_by_value(language)
67
+ driver.language = language
68
+ time.sleep(1)
69
+ ```
70
+
71
+ ```python
72
+ def activate_extension(driver: webdriver.Firefox, name : str):
73
+ language = None
74
+ if hasattr(driver, "language"):
75
+ language = driver.language
76
+ switch_language(driver, "en")
77
+ button = driver.find_element_by_class_name("gui_extension-button_2T7PA")
78
+ button.click()
79
+ time.sleep(1)
80
+ ext = driver.find_element_by_xpath(f'//span[text()="{name.capitalize()}"]')
81
+ ext.click()
82
+ time.sleep(1)
83
+ if language:
84
+ switch_language(driver, language)
85
+ ```
86
+
87
+ ```python
88
+ def scrape_blocks(driver, language="en"):
89
+ #profile.set_preference('intl.accept_languages', language)
90
+ switch_language(driver, language)
91
+ box = driver.find_element_by_class_name("blocklyFlyout")
92
+ svg = box.get_attribute("outerHTML")
93
+ return svg
94
+
95
+ ```
96
+
97
+ ```python
98
+ def fix_svg_and_get_opcodes(svg):
99
+ # adjust path to icons
100
+ svg = svg.replace("/static/blocks-media/", "icons/")
101
+ # create a full xml document
102
+ entities = '<!ENTITY quot "&#34;"> <!ENTITY amp "&#38;"> <!ENTITY apos "&#39;"> <!ENTITY lt "&#60;"> <!ENTITY gt "&#62;"> <!ENTITY nbsp "&#160;"> <!ENTITY iexcl "&#161;"> <!ENTITY cent "&#162;"> <!ENTITY pound "&#163;"> <!ENTITY curren "&#164;"> <!ENTITY yen "&#165;"> <!ENTITY brvbar "&#166;"> <!ENTITY sect "&#167;"> <!ENTITY uml "&#168;"> <!ENTITY copy "&#169;"> <!ENTITY ordf "&#170;"> <!ENTITY laquo "&#171;"> <!ENTITY not "&#172;"> <!ENTITY shy "&#173;"> <!ENTITY reg "&#174;"> <!ENTITY macr "&#175;"> <!ENTITY deg "&#176;"> <!ENTITY plusmn "&#177;"> <!ENTITY sup2 "&#178;"> <!ENTITY sup3 "&#179;"> <!ENTITY acute "&#180;"> <!ENTITY micro "&#181;"> <!ENTITY para "&#182;"> <!ENTITY middot "&#183;"> <!ENTITY cedil "&#184;"> <!ENTITY sup1 "&#185;"> <!ENTITY ordm "&#186;"> <!ENTITY raquo "&#187;"> <!ENTITY frac14 "&#188;"> <!ENTITY frac12 "&#189;"> <!ENTITY frac34 "&#190;"> <!ENTITY iquest "&#191;"> <!ENTITY Agrave "&#192;"> <!ENTITY Aacute "&#193;"> <!ENTITY Acirc "&#194;"> <!ENTITY Atilde "&#195;"> <!ENTITY Auml "&#196;"> <!ENTITY Aring "&#197;"> <!ENTITY AElig "&#198;"> <!ENTITY Ccedil "&#199;"> <!ENTITY Egrave "&#200;"> <!ENTITY Eacute "&#201;"> <!ENTITY Ecirc "&#202;"> <!ENTITY Euml "&#203;"> <!ENTITY Igrave "&#204;"> <!ENTITY Iacute "&#205;"> <!ENTITY Icirc "&#206;"> <!ENTITY Iuml "&#207;"> <!ENTITY ETH "&#208;"> <!ENTITY Ntilde "&#209;"> <!ENTITY Ograve "&#210;"> <!ENTITY Oacute "&#211;"> <!ENTITY Ocirc "&#212;"> <!ENTITY Otilde "&#213;"> <!ENTITY Ouml "&#214;"> <!ENTITY times "&#215;"> <!ENTITY Oslash "&#216;"> <!ENTITY Ugrave "&#217;"> <!ENTITY Uacute "&#218;"> <!ENTITY Ucirc "&#219;"> <!ENTITY Uuml "&#220;"> <!ENTITY Yacute "&#221;"> <!ENTITY THORN "&#222;"> <!ENTITY szlig "&#223;"> <!ENTITY agrave "&#224;"> <!ENTITY aacute "&#225;"> <!ENTITY acirc "&#226;"> <!ENTITY atilde "&#227;"> <!ENTITY auml "&#228;"> <!ENTITY aring "&#229;"> <!ENTITY aelig "&#230;"> <!ENTITY ccedil "&#231;"> <!ENTITY egrave "&#232;"> <!ENTITY eacute "&#233;"> <!ENTITY ecirc "&#234;"> <!ENTITY euml "&#235;"> <!ENTITY igrave "&#236;"> <!ENTITY iacute "&#237;"> <!ENTITY icirc "&#238;"> <!ENTITY iuml "&#239;"> <!ENTITY eth "&#240;"> <!ENTITY ntilde "&#241;"> <!ENTITY ograve "&#242;"> <!ENTITY oacute "&#243;"> <!ENTITY ocirc "&#244;"> <!ENTITY otilde "&#245;"> <!ENTITY ouml "&#246;"> <!ENTITY divide "&#247;"> <!ENTITY oslash "&#248;"> <!ENTITY ugrave "&#249;"> <!ENTITY uacute "&#250;"> <!ENTITY ucirc "&#251;"> <!ENTITY uuml "&#252;"> <!ENTITY yacute "&#253;"> <!ENTITY thorn "&#254;"> <!ENTITY yuml "&#255;"> <!ENTITY OElig "&#338;"> <!ENTITY oelig "&#339;"> <!ENTITY Scaron "&#352;"> <!ENTITY scaron "&#353;"> <!ENTITY Yuml "&#376;"> <!ENTITY fnof "&#402;"> <!ENTITY circ "&#710;"> <!ENTITY tilde "&#732;"> <!ENTITY Alpha "&#913;"> <!ENTITY Beta "&#914;"> <!ENTITY Gamma "&#915;"> <!ENTITY Delta "&#916;"> <!ENTITY Epsilon "&#917;"> <!ENTITY Zeta "&#918;"> <!ENTITY Eta "&#919;"> <!ENTITY Theta "&#920;"> <!ENTITY Iota "&#921;"> <!ENTITY Kappa "&#922;"> <!ENTITY Lambda "&#923;"> <!ENTITY Mu "&#924;"> <!ENTITY Nu "&#925;"> <!ENTITY Xi "&#926;"> <!ENTITY Omicron "&#927;"> <!ENTITY Pi "&#928;"> <!ENTITY Rho "&#929;"> <!ENTITY Sigma "&#931;"> <!ENTITY Tau "&#932;"> <!ENTITY Upsilon "&#933;"> <!ENTITY Phi "&#934;"> <!ENTITY Chi "&#935;"> <!ENTITY Psi "&#936;"> <!ENTITY Omega "&#937;"> <!ENTITY alpha "&#945;"> <!ENTITY beta "&#946;"> <!ENTITY gamma "&#947;"> <!ENTITY delta "&#948;"> <!ENTITY epsilon "&#949;"> <!ENTITY zeta "&#950;"> <!ENTITY eta "&#951;"> <!ENTITY theta "&#952;"> <!ENTITY iota "&#953;"> <!ENTITY kappa "&#954;"> <!ENTITY lambda "&#955;"> <!ENTITY mu "&#956;"> <!ENTITY nu "&#957;"> <!ENTITY xi "&#958;"> <!ENTITY omicron "&#959;"> <!ENTITY pi "&#960;"> <!ENTITY rho "&#961;"> <!ENTITY sigmaf "&#962;"> <!ENTITY sigma "&#963;"> <!ENTITY tau "&#964;"> <!ENTITY upsilon "&#965;"> <!ENTITY phi "&#966;"> <!ENTITY chi "&#967;"> <!ENTITY psi "&#968;"> <!ENTITY omega "&#969;"> <!ENTITY thetasym "&#977;"> <!ENTITY upsih "&#978;"> <!ENTITY piv "&#982;"> <!ENTITY ensp "&#8194;"> <!ENTITY emsp "&#8195;"> <!ENTITY thinsp "&#8201;"> <!ENTITY zwnj "&#8204;"> <!ENTITY zwj "&#8205;"> <!ENTITY lrm "&#8206;"> <!ENTITY rlm "&#8207;"> <!ENTITY ndash "&#8211;"> <!ENTITY mdash "&#8212;"> <!ENTITY lsquo "&#8216;"> <!ENTITY rsquo "&#8217;"> <!ENTITY sbquo "&#8218;"> <!ENTITY ldquo "&#8220;"> <!ENTITY rdquo "&#8221;"> <!ENTITY bdquo "&#8222;"> <!ENTITY dagger "&#8224;"> <!ENTITY Dagger "&#8225;"> <!ENTITY bull "&#8226;"> <!ENTITY hellip "&#8230;"> <!ENTITY permil "&#8240;"> <!ENTITY prime "&#8242;"> <!ENTITY Prime "&#8243;"> <!ENTITY lsaquo "&#8249;"> <!ENTITY rsaquo "&#8250;"> <!ENTITY oline "&#8254;"> <!ENTITY frasl "&#8260;"> <!ENTITY euro "&#8364;"> <!ENTITY image "&#8465;"> <!ENTITY weierp "&#8472;"> <!ENTITY real "&#8476;"> <!ENTITY trade "&#8482;"> <!ENTITY alefsym "&#8501;"> <!ENTITY larr "&#8592;"> <!ENTITY uarr "&#8593;"> <!ENTITY rarr "&#8594;"> <!ENTITY darr "&#8595;"> <!ENTITY harr "&#8596;"> <!ENTITY crarr "&#8629;"> <!ENTITY lArr "&#8656;"> <!ENTITY uArr "&#8657;"> <!ENTITY rArr "&#8658;"> <!ENTITY dArr "&#8659;"> <!ENTITY hArr "&#8660;"> <!ENTITY forall "&#8704;"> <!ENTITY part "&#8706;"> <!ENTITY exist "&#8707;"> <!ENTITY empty "&#8709;"> <!ENTITY nabla "&#8711;"> <!ENTITY isin "&#8712;"> <!ENTITY notin "&#8713;"> <!ENTITY ni "&#8715;"> <!ENTITY prod "&#8719;"> <!ENTITY sum "&#8721;"> <!ENTITY minus "&#8722;"> <!ENTITY lowast "&#8727;"> <!ENTITY radic "&#8730;"> <!ENTITY prop "&#8733;"> <!ENTITY infin "&#8734;"> <!ENTITY ang "&#8736;"> <!ENTITY and "&#8743;"> <!ENTITY or "&#8744;"> <!ENTITY cap "&#8745;"> <!ENTITY cup "&#8746;"> <!ENTITY int "&#8747;"> <!ENTITY there4 "&#8756;"> <!ENTITY sim "&#8764;"> <!ENTITY cong "&#8773;"> <!ENTITY asymp "&#8776;"> <!ENTITY ne "&#8800;"> <!ENTITY equiv "&#8801;"> <!ENTITY le "&#8804;"> <!ENTITY ge "&#8805;"> <!ENTITY sub "&#8834;"> <!ENTITY sup "&#8835;"> <!ENTITY nsub "&#8836;"> <!ENTITY sube "&#8838;"> <!ENTITY supe "&#8839;"> <!ENTITY oplus "&#8853;"> <!ENTITY otimes "&#8855;"> <!ENTITY perp "&#8869;"> <!ENTITY sdot "&#8901;"> <!ENTITY lceil "&#8968;"> <!ENTITY rceil "&#8969;"> <!ENTITY lfloor "&#8970;"> <!ENTITY rfloor "&#8971;"> <!ENTITY lang "&#9001;"> <!ENTITY rang "&#9002;"> <!ENTITY loz "&#9674;"> <!ENTITY spades "&#9824;"> <!ENTITY clubs "&#9827;"> <!ENTITY hearts "&#9829;"> <!ENTITY diams "&#9830;">'
103
+ doctype = '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [ {} ]>'.format(entities)
104
+ xml = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>'
105
+ doc = xml + doctype + svg
106
+ # add namespaces
107
+ doc = doc.replace("<svg ", '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" ')
108
+ # use ElementTree for further modifications
109
+ root = ET.fromstring(doc)
110
+ # Find workspace group, remove other top elements
111
+ workspace = root.find("svg:g", namespaces)
112
+ path = root.find("svg:path", namespaces)
113
+ defs = root.find("svg:defs", namespaces)
114
+ root.remove(path)
115
+ root.remove(defs)
116
+ # Insert the CSS used in Scratch
117
+ root.insert(0, ET.fromstring('''<style xmlns="http://www.w3.org/2000/svg">
118
+ .blocklyPath {
119
+ stroke-width: 1px;
120
+ }
121
+ svg {
122
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
123
+ }
124
+ .blocklyText {
125
+ fill: #fff;
126
+ font-family: "Helvetica Neue", Helvetica, sans-serif;
127
+ font-size: 12pt;
128
+ font-weight: 500;
129
+ }
130
+ .blocklyNonEditableText > text, .blocklyEditableText > text {
131
+ fill: #575E75;
132
+ }
133
+ .blocklyNonEditableText > text.blocklyDropdownText, .blocklyEditableText > text.blocklyDropdownText {
134
+ fill: #fff;
135
+ }
136
+ </style>
137
+ '''))
138
+ # Set some smallish dimensions (will be fixed outside this script later)
139
+ root.attrib["width"] = "400"
140
+ root.attrib["height"] = "80"
141
+ # Remove second child element of workspace (blocks are in first)
142
+ del workspace[1]
143
+ # Unset clip path
144
+ if "clip-path" in workspace.attrib:
145
+ del workspace.attrib["clip-path"]
146
+ # Move all blocks one level up under workspace
147
+ canvas = workspace[0]
148
+ for c in canvas:
149
+ workspace.append(c)
150
+ workspace.remove(canvas)
151
+ # Remove all elements that are no blocks and
152
+ # repair opcodes
153
+ opcodes = []
154
+ for c in workspace:
155
+ # Remove all transforms (they set the position of the blocks)
156
+ if "transform" in c.attrib:
157
+ del c.attrib["transform"]
158
+ # All blocks have a data-id with (almost) an opcode
159
+ if "data-id" in c.attrib:
160
+ # Fix sensing_of
161
+ if c.attrib["data-id"] == "of":
162
+ c.attrib["data-id"] = "sensing_of"
163
+ if "data-category" in c.attrib:
164
+ # we use the data category to fix some opcodes
165
+ # unfortunately, sounds and operators need to be renamed
166
+ if c.attrib["data-category"] == "sounds":
167
+ c.attrib["data-category"] = "sound"
168
+ if c.attrib["data-category"] == "operators":
169
+ c.attrib["data-category"] = "operator"
170
+ if c.attrib["data-category"] == "events":
171
+ c.attrib["data-category"] = "event"
172
+ # And for extensions they use translations... aaargh!
173
+ if c.attrib["data-id"].startswith("pen"):
174
+ c.attrib["data-category"] = "pen"
175
+ # some blocks have random id parts, we need to remove these
176
+ parts = c.attrib["data-id"].split("_")
177
+ for p in parts[::-1]:
178
+ if not_letters.search(p):
179
+ parts.remove(p)
180
+ if len(parts)==0:
181
+ continue
182
+ c.attrib["data-id"] = "_".join(parts)
183
+ # Finally, we can repair all blocks so that the id is the opcode
184
+ if c.attrib["data-id"].startswith("|"):
185
+ c.attrib["data-id"] = c.attrib["data-id"][c.attrib["data-id"].index("_") + 1:]
186
+ if not c.attrib["data-id"].startswith(c.attrib["data-category"]):
187
+ c.attrib["data-id"] = c.attrib["data-category"] + "_" + c.attrib["data-id"]
188
+ opcodes.append(c.attrib["data-id"])
189
+ opcodes.sort()
190
+ print(f"Found {len(opcodes)} blocks.")
191
+ return opcodes, root
192
+ ```
193
+
194
+ ```python
195
+ def save_blocks(opcodes, root, language):
196
+ Path(f"svg/{language}").mkdir(parents=True, exist_ok=True)
197
+ for opcode in opcodes:
198
+ # print(opcode)
199
+ # Create a copy for this block
200
+ root2 = copy.deepcopy(root)
201
+ # remove everything else
202
+ for c in root2[1][::-1]:
203
+ if not "data-id" in c.attrib or c.attrib["data-id"]!=opcode:
204
+ root2[1].remove(c)
205
+ # Include the icon svg as nested svg (otherwise it gets blurred in inkscape)
206
+ for imageparent in root2.findall('.//svg:image/..', namespaces):
207
+ image = imageparent.find('svg:image', namespaces)
208
+ index = list(imageparent).index(image)
209
+ filename = image.attrib["{http://www.w3.org/1999/xlink}href"]
210
+ # Extensions use data URIs...
211
+ innersvg = ""
212
+ if filename.startswith("data:image/svg+xml;base64,"):
213
+ innersvg = filename[len("data:image/svg+xml;base64"):]
214
+ innersvg = base64.decodebytes(innersvg.encode("utf-8")).decode("utf-8")
215
+ else:
216
+ with open(filename, "r", encoding="utf-8") as f:
217
+ innersvg = f.read()
218
+ innersvg = innersvg[innersvg.index("<svg"):]
219
+ newimage = ET.fromstring(f'''<g xmlns="http://www.w3.org/2000/svg">
220
+ {innersvg}
221
+ </g>
222
+ ''')
223
+ newimage[0].attrib["width"] = image.attrib["width"]
224
+ newimage[0].attrib["height"] = image.attrib["height"]
225
+ if "transform" in image.attrib:
226
+ newimage.attrib["transform"] = image.attrib["transform"]
227
+ imageparent.insert(index, newimage)
228
+ imageparent.remove(image)
229
+
230
+ # display(SVG(ET.tostring(root2)))
231
+ # Finally, write the SVG
232
+ with open(f"svg/{language}/{opcode}.svg", "wb") as f:
233
+ f.write(ET.tostring(root2))
234
+ ```
235
+
236
+ ```python
237
+ driver = start_selenium()
238
+ activate_extension(driver, "pen")
239
+ with open("langs.json", "r", encoding="utf-8") as f:
240
+ languages = json.load(f)
241
+ for lang in languages:
242
+ print(f"Language {lang}")
243
+ svg = scrape_blocks(driver, lang)
244
+ opcodes, root = fix_svg_and_get_opcodes(svg)
245
+ save_blocks(opcodes, root, lang)
246
+ ```
247
+
248
+ ```python
249
+
250
+ ```
@@ -0,0 +1,19 @@
1
+ #!/bin/bash
2
+ # Export pngs
3
+ # Density can be used for scaling, 96 DPI is default
4
+ if [ -z "$1" ]
5
+ then
6
+ density=96
7
+ else
8
+ density=$1
9
+ fi
10
+
11
+
12
+ for i in $(find svg -name \*.svg)
13
+ do
14
+ out=${i#svg}
15
+ out="png${density}${out%svg}png"
16
+ mkdir -p $(dirname "$out")
17
+ echo "$i -> $out"
18
+ inkscape $i -o $out -d $density > /dev/null 2>&1
19
+ done
@@ -0,0 +1,73 @@
1
+ {
2
+ "ab": "Аҧсшәа",
3
+ "af": "Afrikaans",
4
+ "ar": "العربية",
5
+ "am": "አማርኛ",
6
+ "az": "Azeri",
7
+ "id": "Bahasa Indonesia",
8
+ "be": "Беларуская",
9
+ "bg": "Български",
10
+ "ca": "Català",
11
+ "cs": "Česky",
12
+ "cy": "Cymraeg",
13
+ "da": "Dansk",
14
+ "de": "Deutsch",
15
+ "et": "Eesti",
16
+ "el": "Ελληνικά",
17
+ "en": "English",
18
+ "es": "Español (España)",
19
+ "es-419": "Español Latinoamericano",
20
+ "eu": "Euskara",
21
+ "fa": "فارسی",
22
+ "fr": "Français",
23
+ "ga": "Gaeilge",
24
+ "gd": "Gàidhlig",
25
+ "gl": "Galego",
26
+ "ko": "한국어",
27
+ "hy": "Հայերեն",
28
+ "he": "עִבְרִית",
29
+ "hr": "Hrvatski",
30
+ "xh": "isiXhosa",
31
+ "zu": "isiZulu",
32
+ "is": "Íslenska",
33
+ "it": "Italiano",
34
+ "ka": "ქართული ენა",
35
+ "kk": "қазақша",
36
+ "qu": "Kichwa",
37
+ "sw": "Kiswahili",
38
+ "ht": "Kreyòl ayisyen",
39
+ "ku": "Kurdî",
40
+ "ckb": "کوردیی ناوەندی",
41
+ "lv": "Latviešu",
42
+ "lt": "Lietuvių",
43
+ "hu": "Magyar",
44
+ "mi": "Māori",
45
+ "mn": "Монгол хэл",
46
+ "nl": "Nederlands",
47
+ "ja": "日本語",
48
+ "ja-Hira": "にほんご",
49
+ "nb": "Norsk Bokmål",
50
+ "nn": "Norsk Nynorsk",
51
+ "or": "ଓଡ଼ିଆ",
52
+ "uz": "Oʻzbekcha",
53
+ "th": "ไทย",
54
+ "km": "ភាសាខ្មែរ",
55
+ "pl": "Polski",
56
+ "pt": "Português",
57
+ "pt-br": "Português Brasileiro",
58
+ "rap": "Rapa Nui",
59
+ "ro": "Română",
60
+ "ru": "Русский",
61
+ "nso": "Sepedi",
62
+ "tn": "Setswana",
63
+ "sk": "Slovenčina",
64
+ "sl": "Slovenščina",
65
+ "sr": "Српски",
66
+ "fi": "Suomi",
67
+ "sv": "Svenska",
68
+ "vi": "Tiếng Việt",
69
+ "tr": "Türkçe",
70
+ "uk": "Українська",
71
+ "zh-cn": "简体中文",
72
+ "zh-tw": "繁體中文"
73
+ }
@@ -0,0 +1,20 @@
1
+ # Minimal makefile for Sphinx documentation
2
+ #
3
+
4
+ # You can set these variables from the command line, and also
5
+ # from the environment for the first two.
6
+ SPHINXOPTS ?=
7
+ SPHINXBUILD ?= sphinx-build
8
+ SOURCEDIR = source
9
+ BUILDDIR = build
10
+
11
+ # Put it first so that "make" without argument is like "make help".
12
+ help:
13
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14
+
15
+ .PHONY: help Makefile
16
+
17
+ # Catch-all target: route all unknown targets to Sphinx using the new
18
+ # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19
+ %: Makefile
20
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@@ -0,0 +1,29 @@
1
+ # PyStage Documentation
2
+
3
+ ## How to
4
+
5
+ This documentation is generated with Sphinx (install it with pip e.g.).
6
+
7
+ The ```source``` directory contains the raw files for the documentation. Out of these files we can build
8
+ the documentation in html, pdf etc.
9
+
10
+ 1. To generate the source files run from within this directory:
11
+
12
+ ```sphinx-apidoc -f -o source ../src/pystage/ -t source/_templates -E```
13
+ * ```-t```: The path to the templates directory (optional)
14
+ * ```-E```: Exclude submodule headings (optional)
15
+
16
+ 2. Afterwards generate the html docu by running:
17
+
18
+ ```make html```
19
+
20
+
21
+ ## Include images
22
+
23
+ Images can be included using restructured Text:
24
+
25
+ ```.. figure:: _static/image.png```
26
+
27
+ It is also possible to put the image directly in a function documentation. Therefore, put
28
+ the image directly in the docstring of the function. Make sure to have a blank line above and below
29
+ of the reST element. The path to the image must be relative to the place of the docstring.
@@ -0,0 +1,2 @@
1
+ sphinx-apidoc -f -o source ../src/pystage/
2
+ make clean && make html
@@ -0,0 +1,35 @@
1
+ @ECHO OFF
2
+
3
+ pushd %~dp0
4
+
5
+ REM Command file for Sphinx documentation
6
+
7
+ if "%SPHINXBUILD%" == "" (
8
+ set SPHINXBUILD=sphinx-build
9
+ )
10
+ set SOURCEDIR=source
11
+ set BUILDDIR=build
12
+
13
+ if "%1" == "" goto help
14
+
15
+ %SPHINXBUILD% >NUL 2>NUL
16
+ if errorlevel 9009 (
17
+ echo.
18
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
19
+ echo.installed, then set the SPHINXBUILD environment variable to point
20
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
21
+ echo.may add the Sphinx directory to PATH.
22
+ echo.
23
+ echo.If you don't have Sphinx installed, grab it from
24
+ echo.http://sphinx-doc.org/
25
+ exit /b 1
26
+ )
27
+
28
+ %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
29
+ goto end
30
+
31
+ :help
32
+ %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
33
+
34
+ :end
35
+ popd
Binary file
@@ -0,0 +1,6 @@
1
+ m2r2
2
+ myst_parser
3
+ pygame
4
+ svglib
5
+ reportlab
6
+ sphinx_panels
@@ -0,0 +1,8 @@
1
+ {%- if show_headings %}
2
+ {{- [basename, "module"] | join(' ') | e | heading }}
3
+
4
+ {% endif -%}
5
+ .. automodule:: {{ qualname }}
6
+ {%- for option in automodule_options %}
7
+ :{{ option }}:
8
+ {%- endfor %}
@@ -0,0 +1,51 @@
1
+ {%- macro automodule(modname, options) -%}
2
+ .. automodule:: {{ modname }}
3
+ {%- for option in options %}
4
+ :{{ option }}:
5
+ {%- endfor %}
6
+ {%- endmacro %}
7
+
8
+ {%- macro toctree(docnames) -%}
9
+ .. toctree::
10
+ :maxdepth: {{ maxdepth }}
11
+ {% for docname in docnames %}
12
+ {{ docname }}
13
+ {%- endfor %}
14
+ {%- endmacro %}
15
+
16
+ {%- if is_namespace %}
17
+ {{- [pkgname, "namespace"] | join(" ") | e | heading }}
18
+ {% else %}
19
+ {{- [pkgname] | join(" ") | e | heading }}
20
+ {% endif %}
21
+
22
+ {{ [".. _", pkgname, ":"] | join("") }}
23
+
24
+ {%- if modulefirst and not is_namespace %}
25
+ {{ automodule(pkgname, automodule_options) }}
26
+ {% endif %}
27
+
28
+ {%- if subpackages %}
29
+ Subpackages
30
+ -----------
31
+
32
+ {{ toctree(subpackages) }}
33
+ {% endif %}
34
+
35
+ {%- if submodules %}
36
+
37
+ {% if separatemodules %}
38
+ {{ toctree(submodules) }}
39
+ {% else %}
40
+ {%- for submodule in submodules %}
41
+ {% if show_headings %}
42
+ {{- [submodule] | join(" ") | e | heading(2) }}
43
+ {% endif %}
44
+ {{ automodule(submodule, automodule_options) }}
45
+ {% endfor %}
46
+ {%- endif %}
47
+ {%- endif %}
48
+
49
+ {%- if not modulefirst and not is_namespace %}
50
+
51
+ {% endif %}