Compare commits

...

No commits in common. 'master' and 'gh-pages' have entirely different histories.

  1. 107
      .gitignore
  2. 3
      .gitmodules
  3. 21
      LICENSE
  4. 522
      Links/index.html
  5. 521
      Organization/index.html
  6. 531
      PandocA/index.html
  7. 529
      PandocB/index.html
  8. 500
      PandocC/index.html
  9. 543
      PanfluteA/index.html
  10. 609
      PanfluteB/index.html
  11. 14
      README.md
  12. 611
      Setup/index.html
  13. 500
      Testing/index.html
  14. 62
      api_translate
  15. 4
      assets/fonts/font-awesome.css
  16. 13
      assets/fonts/material-icons.css
  17. BIN
      assets/fonts/specimen/FontAwesome.ttf
  18. BIN
      assets/fonts/specimen/FontAwesome.woff
  19. BIN
      assets/fonts/specimen/FontAwesome.woff2
  20. BIN
      assets/fonts/specimen/MaterialIcons-Regular.ttf
  21. BIN
      assets/fonts/specimen/MaterialIcons-Regular.woff
  22. BIN
      assets/fonts/specimen/MaterialIcons-Regular.woff2
  23. BIN
      assets/images/favicon.png
  24. 20
      assets/images/icons/bitbucket.1b09e088.svg
  25. 18
      assets/images/icons/github.f0b8504a.svg
  26. 38
      assets/images/icons/gitlab.6dd19c00.svg
  27. 1
      assets/javascripts/application.e72fd936.js
  28. 1
      assets/javascripts/lunr/lunr.da.js
  29. 1
      assets/javascripts/lunr/lunr.de.js
  30. 1
      assets/javascripts/lunr/lunr.du.js
  31. 1
      assets/javascripts/lunr/lunr.es.js
  32. 1
      assets/javascripts/lunr/lunr.fi.js
  33. 1
      assets/javascripts/lunr/lunr.fr.js
  34. 1
      assets/javascripts/lunr/lunr.hu.js
  35. 1
      assets/javascripts/lunr/lunr.it.js
  36. 1
      assets/javascripts/lunr/lunr.jp.js
  37. 1
      assets/javascripts/lunr/lunr.multi.js
  38. 1
      assets/javascripts/lunr/lunr.no.js
  39. 1
      assets/javascripts/lunr/lunr.pt.js
  40. 1
      assets/javascripts/lunr/lunr.ro.js
  41. 1
      assets/javascripts/lunr/lunr.ru.js
  42. 1
      assets/javascripts/lunr/lunr.stemmer.support.js
  43. 1
      assets/javascripts/lunr/lunr.sv.js
  44. 1
      assets/javascripts/lunr/lunr.tr.js
  45. 1
      assets/javascripts/lunr/tinyseg.js
  46. 1
      assets/javascripts/modernizr.1aa3b519.js
  47. 1176
      assets/stylesheets/application-palette.22915126.css
  48. 2552
      assets/stylesheets/application.451f80e5.css
  49. 23
      docs/Links.md
  50. 87
      docs/Organization.md
  51. 34
      docs/PandocA.md
  52. 31
      docs/PandocB.md
  53. 12
      docs/PandocC.md
  54. 120
      docs/PanfluteA.md
  55. 66
      docs/PanfluteB.md
  56. 90
      docs/Setup.md
  57. 14
      docs/Testing.md
  58. 71
      docs/index.md
  59. 86
      filters/ruskie.py
  60. 0
      filters/shift_images.py
  61. 68
      filters/shift_links.py
  62. 34
      filters/strip_everything.py
  63. 86
      filters/translate.py
  64. 611
      index.html
  65. 1
      mkdocs-material
  66. 46
      mkdocs.yml
  67. 2986
      search/lunr.js
  68. 94
      search/main.js
  69. 1
      search/search_index.json
  70. 127
      search/worker.js
  71. 53
      sitemap.xml
  72. BIN
      sitemap.xml.gz
  73. 67
      source/index.md
  74. BIN
      source/sheep.jpg
  75. BIN
      source/shepherd.jpg
  76. 165
      source/shepherd.md
  77. 79
      translate

107
.gitignore vendored

@ -1,107 +0,0 @@
# No credentials
*.json
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/

3
.gitmodules vendored

@ -1,3 +0,0 @@
[submodule "mkdocs-material"]
path = mkdocs-material
url = https://git.charlesreid1.com/charlesreid1/mkdocs-material.git

21
LICENSE

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2018 Chaz Reid
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

522
Links/index.html

@ -0,0 +1,522 @@
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link rel="canonical" href="https://pages.charlesreid1.com/translate-yer-docs/Links/">
<meta name="lang:clipboard.copy" content="Copy to clipboard">
<meta name="lang:clipboard.copied" content="Copied to clipboard">
<meta name="lang:search.language" content="en">
<meta name="lang:search.pipeline.stopwords" content="True">
<meta name="lang:search.pipeline.trimmer" content="True">
<meta name="lang:search.result.none" content="No matching documents">
<meta name="lang:search.result.one" content="1 matching document">
<meta name="lang:search.result.other" content="# matching documents">
<meta name="lang:search.tokenizer" content="[\s\-]+">
<link rel="shortcut icon" href="..">
<meta name="generator" content="mkdocs-1.0, mkdocs-material-3.0.3">
<title>Links - translate-yer-docs</title>
<link rel="stylesheet" href="../assets/stylesheets/application.451f80e5.css">
<link rel="stylesheet" href="../assets/stylesheets/application-palette.22915126.css">
<meta name="theme-color" content="#3f51b5">
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script>
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Ubuntu:300,400,400i,700|Ubuntu+Mono">
<style>body,input{font-family:"Ubuntu","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Ubuntu Mono","Courier New",Courier,monospace}</style>
<link rel="stylesheet" href="../assets/fonts/material-icons.css">
<link rel="stylesheet" href="../css/custom.css">
</head>
<body dir="ltr" data-md-color-primary="indigo" data-md-color-accent="indigo">
<svg class="md-svg">
<defs>
</defs>
</svg>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
<a href="../#useful-links" tabindex="1" class="md-skip">
Skip to content
</a>
<header class="md-header" data-md-component="header">
<nav class="md-header-nav md-grid">
<div class="md-flex">
<div class="md-flex__cell md-flex__cell--shrink">
<a href="https://pages.charlesreid1.com/translate-yer-docs" title="translate-yer-docs" class="md-header-nav__button md-logo">
<i class="md-icon">insert_drive_file arrow_right_alt g_translate arrow_right_alt insert_drive_file</i>
</a>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--menu md-header-nav__button" for="__drawer"></label>
</div>
<div class="md-flex__cell md-flex__cell--stretch">
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title">
<span class="md-header-nav__topic">
translate-yer-docs
</span>
<span class="md-header-nav__topic">
Links
</span>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--search md-header-nav__button" for="__search"></label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active">
<label class="md-icon md-search__icon" for="__search"></label>
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1">
&#xE5CD;
</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="result">
<div class="md-search-result__meta">
Type to start searching
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<div class="md-header-nav__source">
<a href="https://git.charlesreid1.com/charlesreid1/translate-yer-docs" title="Go to repository" class="md-source" data-md-source="">
<div class="md-source__repository">
translate-yer-docs
</div>
</a>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container">
<main class="md-main">
<div class="md-main__inner md-grid" data-md-component="container">
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" data-md-level="0">
<label class="md-nav__title md-nav__title--site" for="__drawer">
<a href="https://pages.charlesreid1.com/translate-yer-docs" title="translate-yer-docs" class="md-nav__button md-logo">
<i class="md-icon">insert_drive_file arrow_right_alt g_translate arrow_right_alt insert_drive_file</i>
</a>
translate-yer-docs
</label>
<div class="md-nav__source">
<a href="https://git.charlesreid1.com/charlesreid1/translate-yer-docs" title="Go to repository" class="md-source" data-md-source="">
<div class="md-source__repository">
translate-yer-docs
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." title="Home" class="md-nav__link">
Home
</a>
</li>
<li class="md-nav__item">
<a href="../Organization/" title="How This Repo is Organized" class="md-nav__link">
How This Repo is Organized
</a>
</li>
<li class="md-nav__item">
<a href="../Setup/" title="Setup" class="md-nav__link">
Setup
</a>
</li>
<li class="md-nav__item">
<a href="../PandocA/" title="Pandoc: Markdown to JSON" class="md-nav__link">
Pandoc: Markdown to JSON
</a>
</li>
<li class="md-nav__item">
<a href="../PandocB/" title="Pandoc: JSON to JSON" class="md-nav__link">
Pandoc: JSON to JSON
</a>
</li>
<li class="md-nav__item">
<a href="../PanfluteA/" title="Panflute: Translate" class="md-nav__link">
Panflute: Translate
</a>
</li>
<li class="md-nav__item">
<a href="../PanfluteB/" title="Panflute: Page Elements" class="md-nav__link">
Panflute: Page Elements
</a>
</li>
<li class="md-nav__item">
<a href="../PandocC/" title="Pandoc: JSON to Markdown" class="md-nav__link">
Pandoc: JSON to Markdown
</a>
</li>
<li class="md-nav__item">
<a href="../Testing/" title="Testing" class="md-nav__link">
Testing
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
Links
</label>
<a href="./" title="Links" class="md-nav__link md-nav__link--active">
Links
</a>
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#useful-links" title="Useful Links" class="md-nav__link">
Useful Links
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#useful-links" title="Useful Links" class="md-nav__link">
Useful Links
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content">
<article class="md-content__inner md-typeset">
<h1>Links</h1>
<h2 id="useful-links">Useful Links<a class="headerlink" href="#useful-links" title="Permanent link">&para;</a></h2>
<ul>
<li>
<p>Markdown to structured JSON using pandoc: </p>
<ul>
<li><a href="https://hackage.haskell.org/package/pandoc-types-1.17.4.2/docs/Text-Pandoc-JSON.html">Text.Pandoc.JSON</a></li>
</ul>
</li>
<li>
<p>How to write Pandoc filters using Python: </p>
<ul>
<li><a href="https://pypi.org/project/pandocfilters/">pandocfilters</a></li>
</ul>
</li>
<li>
<p>Example reading from stdin:</p>
<ul>
<li><code>pandoc -t json -s | ./caps.py | pandoc -f json</code></li>
</ul>
</li>
<li>
<p>Link to examples:</p>
<ul>
<li><a href="https://github.com/jgm/pandocfilters/tree/master/examples">pandocfilters examples</a></li>
<li><a href="https://github.com/jgm/pandocfilters/blob/master/examples/caps.py">caps.py</a></li>
</ul>
</li>
<li>
<p>requests library Python:</p>
<ul>
<li><a href="http://docs.python-requests.org/en/latest/user/quickstart/">requests quickstart</a></li>
<li><code>&gt;&gt;&gt; r = requests.put('http://httpbin.org/put', data = {'key':'value'})</code></li>
</ul>
</li>
<li>
<p>pandocfilters</p>
<ul>
<li><a href="https://github.com/jgm/pandocfilters">pandocfilters</a></li>
<li>also see <a href="http://pandoc.org/filters.html#but-i-dont-want-to-learn-haskell">but i don't want to learn haskell</a> on pandoc.org.</li>
</ul>
</li>
</ul>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href="../Testing/" title="Testing" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div>
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Previous
</span>
Testing
</span>
</div>
</a>
</nav>
</div>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
<div class="md-footer-copyright__highlight">
Copyright &copy; 2018 <a href="https://charlesreid1.com">Charles Reid</a>, released under the <a href="https://opensource.org/licenses/MIT">MIT License</a>.
</div>
powered by
<a href="https://www.mkdocs.org">MkDocs</a>
and
<a href="https://squidfunk.github.io/mkdocs-material/">
Material for MkDocs</a>
</div>
</div>
</div>
</footer>
</div>
<script src="../assets/javascripts/application.e72fd936.js"></script>
<script>app.initialize({version:"1.0",url:{base:".."}})</script>
<script src="../search/main.js"></script>
</body>
</html>

521
Organization/index.html

@ -0,0 +1,521 @@
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link rel="canonical" href="https://pages.charlesreid1.com/translate-yer-docs/Organization/">
<meta name="lang:clipboard.copy" content="Copy to clipboard">
<meta name="lang:clipboard.copied" content="Copied to clipboard">
<meta name="lang:search.language" content="en">
<meta name="lang:search.pipeline.stopwords" content="True">
<meta name="lang:search.pipeline.trimmer" content="True">
<meta name="lang:search.result.none" content="No matching documents">
<meta name="lang:search.result.one" content="1 matching document">
<meta name="lang:search.result.other" content="# matching documents">
<meta name="lang:search.tokenizer" content="[\s\-]+">
<link rel="shortcut icon" href="..">
<meta name="generator" content="mkdocs-1.0, mkdocs-material-3.0.3">
<title>How This Repo is Organized - translate-yer-docs</title>
<link rel="stylesheet" href="../assets/stylesheets/application.451f80e5.css">
<link rel="stylesheet" href="../assets/stylesheets/application-palette.22915126.css">
<meta name="theme-color" content="#3f51b5">
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script>
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Ubuntu:300,400,400i,700|Ubuntu+Mono">
<style>body,input{font-family:"Ubuntu","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Ubuntu Mono","Courier New",Courier,monospace}</style>
<link rel="stylesheet" href="../assets/fonts/material-icons.css">
<link rel="stylesheet" href="../css/custom.css">
</head>
<body dir="ltr" data-md-color-primary="indigo" data-md-color-accent="indigo">
<svg class="md-svg">
<defs>
</defs>
</svg>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
<a href="../#documentation" tabindex="1" class="md-skip">
Skip to content
</a>
<header class="md-header" data-md-component="header">
<nav class="md-header-nav md-grid">
<div class="md-flex">
<div class="md-flex__cell md-flex__cell--shrink">
<a href="https://pages.charlesreid1.com/translate-yer-docs" title="translate-yer-docs" class="md-header-nav__button md-logo">
<i class="md-icon">insert_drive_file arrow_right_alt g_translate arrow_right_alt insert_drive_file</i>
</a>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--menu md-header-nav__button" for="__drawer"></label>
</div>
<div class="md-flex__cell md-flex__cell--stretch">
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title">
<span class="md-header-nav__topic">
translate-yer-docs
</span>
<span class="md-header-nav__topic">
How This Repo is Organized
</span>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--search md-header-nav__button" for="__search"></label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active">
<label class="md-icon md-search__icon" for="__search"></label>
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1">
&#xE5CD;
</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="result">
<div class="md-search-result__meta">
Type to start searching
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<div class="md-header-nav__source">
<a href="https://git.charlesreid1.com/charlesreid1/translate-yer-docs" title="Go to repository" class="md-source" data-md-source="">
<div class="md-source__repository">
translate-yer-docs
</div>
</a>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container">
<main class="md-main">
<div class="md-main__inner md-grid" data-md-component="container">
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" data-md-level="0">
<label class="md-nav__title md-nav__title--site" for="__drawer">
<a href="https://pages.charlesreid1.com/translate-yer-docs" title="translate-yer-docs" class="md-nav__button md-logo">
<i class="md-icon">insert_drive_file arrow_right_alt g_translate arrow_right_alt insert_drive_file</i>
</a>
translate-yer-docs
</label>
<div class="md-nav__source">
<a href="https://git.charlesreid1.com/charlesreid1/translate-yer-docs" title="Go to repository" class="md-source" data-md-source="">
<div class="md-source__repository">
translate-yer-docs
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." title="Home" class="md-nav__link">
Home
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<a href="./" title="How This Repo is Organized" class="md-nav__link md-nav__link--active">
How This Repo is Organized
</a>
</li>
<li class="md-nav__item">
<a href="../Setup/" title="Setup" class="md-nav__link">
Setup
</a>
</li>
<li class="md-nav__item">
<a href="../PandocA/" title="Pandoc: Markdown to JSON" class="md-nav__link">
Pandoc: Markdown to JSON
</a>
</li>
<li class="md-nav__item">
<a href="../PandocB/" title="Pandoc: JSON to JSON" class="md-nav__link">
Pandoc: JSON to JSON
</a>
</li>
<li class="md-nav__item">
<a href="../PanfluteA/" title="Panflute: Translate" class="md-nav__link">
Panflute: Translate
</a>
</li>
<li class="md-nav__item">
<a href="../PanfluteB/" title="Panflute: Page Elements" class="md-nav__link">
Panflute: Page Elements
</a>
</li>
<li class="md-nav__item">
<a href="../PandocC/" title="Pandoc: JSON to Markdown" class="md-nav__link">
Pandoc: JSON to Markdown
</a>
</li>
<li class="md-nav__item">
<a href="../Testing/" title="Testing" class="md-nav__link">
Testing
</a>
</li>
<li class="md-nav__item">
<a href="../Links/" title="Links" class="md-nav__link">
Links
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
</nav>
</div>
</div>
</div>
<div class="md-content">
<article class="md-content__inner md-typeset">
<p>Here is a rundown of the directory structure
of translate the docs:</p>
<h2 id="documentation">Documentation<a class="headerlink" href="#documentation" title="Permanent link">&para;</a></h2>
<p>All of the documentation for how to translate the docs
lives in markdown files in <code>docs/</code>.</p>
<p>This is converted to HTML documentation using <code>mkdocs</code>.</p>
<p>The configuration for mkdocs is in <code>mkdocs.yml</code>.</p>
<p>The mkdocs theme used is mkdocs-material, which is in the
git submodule <code>mkdocs-material/</code>.</p>
<p>The static content is on the <code>gh-pages</code> branch and is hosted
on <code>https://pages.charlesreid1.com/</code> and on Github Pages.</p>
<h2 id="translation">Translation<a class="headerlink" href="#translation" title="Permanent link">&para;</a></h2>
<p>The document is first parsed with pandoc to convert markdown
to JSON.</p>
<p>The JSON is passed to a panflute filter, which processes the text.</p>
<p>Translation magic happens using the Google Cloud Translate API,
which is called by the panflute filter.</p>
<p>Pandoc is used to convert the JSON back to (translated) markdown.</p>
<h1 id="plans">Plans<a class="headerlink" href="#plans" title="Permanent link">&para;</a></h1>
<p>The tool in this repository (the pandoc filter) will eventually
become a command line tool that can be run in-place from any
repository, and the translated markdown deposited into a new
directory.</p>
<p>This requires one major design change: rather than using pandoc
and applying filters from the command line, we must call the
pandoc API from Python directly. Then we can define the filter
as part of the command line tool, and when we call the translate
the docs tool, it applies the filter in-place.</p>
<p>The end result, for the user, is the ability to run a single command
that will translate their docs:</p>
<div class="codehilite"><pre><span></span>$ translate_the_docs --list-languages
ru
de
es
fr
ar
...
$ translate_the_docs
Before we can translate your docs, we will start with a few questions.
What directory contains your current markdown docs?
Leave empty for default: docs
Answer: docs
What language do you want to translate your markdown docs into?
Type ? for a list of languages.
Answer: ?
Possible languages: ru, de, es, fr, ar, ...
What language do you want to translate your markdown docs into?
Type ? for a list of languages.
Answer: ru
What directory do you want to contain your translated markdown docs?
Leave empty for default: ru_docs
Answer:
Translating...
Done!
</pre></div>
<p>Or set with command line options:</p>
<div class="codehilite"><pre><span></span>$ translate_the_docs --source=doc/ --target=ru_docs --language=ru
</pre></div>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href=".." title="Home" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div>
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Previous
</span>
Home
</span>
</div>
</a>
<a href="../Setup/" title="Setup" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Next
</span>
Setup
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i>
</div>
</a>
</nav>
</div>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
<div class="md-footer-copyright__highlight">
Copyright &copy; 2018 <a href="https://charlesreid1.com">Charles Reid</a>, released under the <a href="https://opensource.org/licenses/MIT">MIT License</a>.
</div>
powered by
<a href="https://www.mkdocs.org">MkDocs</a>
and
<a href="https://squidfunk.github.io/mkdocs-material/">
Material for MkDocs</a>
</div>
</div>
</div>
</footer>
</div>
<script src="../assets/javascripts/application.e72fd936.js"></script>
<script>app.initialize({version:"1.0",url:{base:".."}})</script>
<script src="../search/main.js"></script>
</body>
</html>

531
PandocA/index.html

@ -0,0 +1,531 @@
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link rel="canonical" href="https://pages.charlesreid1.com/translate-yer-docs/PandocA/">
<meta name="lang:clipboard.copy" content="Copy to clipboard">
<meta name="lang:clipboard.copied" content="Copied to clipboard">
<meta name="lang:search.language" content="en">
<meta name="lang:search.pipeline.stopwords" content="True">
<meta name="lang:search.pipeline.trimmer" content="True">
<meta name="lang:search.result.none" content="No matching documents">
<meta name="lang:search.result.one" content="1 matching document">
<meta name="lang:search.result.other" content="# matching documents">
<meta name="lang:search.tokenizer" content="[\s\-]+">
<link rel="shortcut icon" href="..">
<meta name="generator" content="mkdocs-1.0, mkdocs-material-3.0.3">
<title>Pandoc: Markdown to JSON - translate-yer-docs</title>
<link rel="stylesheet" href="../assets/stylesheets/application.451f80e5.css">
<link rel="stylesheet" href="../assets/stylesheets/application-palette.22915126.css">
<meta name="theme-color" content="#3f51b5">
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script>
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Ubuntu:300,400,400i,700|Ubuntu+Mono">
<style>body,input{font-family:"Ubuntu","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Ubuntu Mono","Courier New",Courier,monospace}</style>
<link rel="stylesheet" href="../assets/fonts/material-icons.css">
<link rel="stylesheet" href="../css/custom.css">
</head>
<body dir="ltr" data-md-color-primary="indigo" data-md-color-accent="indigo">
<svg class="md-svg">
<defs>
</defs>
</svg>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
<a href="../#using-the-pandoc-api-new-way" tabindex="1" class="md-skip">
Skip to content
</a>
<header class="md-header" data-md-component="header">
<nav class="md-header-nav md-grid">
<div class="md-flex">
<div class="md-flex__cell md-flex__cell--shrink">
<a href="https://pages.charlesreid1.com/translate-yer-docs" title="translate-yer-docs" class="md-header-nav__button md-logo">
<i class="md-icon">insert_drive_file arrow_right_alt g_translate arrow_right_alt insert_drive_file</i>
</a>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--menu md-header-nav__button" for="__drawer"></label>
</div>
<div class="md-flex__cell md-flex__cell--stretch">
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title">
<span class="md-header-nav__topic">
translate-yer-docs
</span>
<span class="md-header-nav__topic">
Pandoc: Markdown to JSON
</span>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--search md-header-nav__button" for="__search"></label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active">
<label class="md-icon md-search__icon" for="__search"></label>
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1">
&#xE5CD;
</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="result">
<div class="md-search-result__meta">
Type to start searching
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<div class="md-header-nav__source">
<a href="https://git.charlesreid1.com/charlesreid1/translate-yer-docs" title="Go to repository" class="md-source" data-md-source="">
<div class="md-source__repository">
translate-yer-docs
</div>
</a>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container">
<main class="md-main">
<div class="md-main__inner md-grid" data-md-component="container">
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" data-md-level="0">
<label class="md-nav__title md-nav__title--site" for="__drawer">
<a href="https://pages.charlesreid1.com/translate-yer-docs" title="translate-yer-docs" class="md-nav__button md-logo">
<i class="md-icon">insert_drive_file arrow_right_alt g_translate arrow_right_alt insert_drive_file</i>
</a>
translate-yer-docs
</label>
<div class="md-nav__source">
<a href="https://git.charlesreid1.com/charlesreid1/translate-yer-docs" title="Go to repository" class="md-source" data-md-source="">
<div class="md-source__repository">
translate-yer-docs
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." title="Home" class="md-nav__link">
Home
</a>
</li>
<li class="md-nav__item">
<a href="../Organization/" title="How This Repo is Organized" class="md-nav__link">
How This Repo is Organized
</a>
</li>
<li class="md-nav__item">
<a href="../Setup/" title="Setup" class="md-nav__link">
Setup
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
Pandoc: Markdown to JSON
</label>
<a href="./" title="Pandoc: Markdown to JSON" class="md-nav__link md-nav__link--active">
Pandoc: Markdown to JSON
</a>
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#using-the-pandoc-api-new-way" title="Using the Pandoc API (New Way)" class="md-nav__link">
Using the Pandoc API (New Way)
</a>
</li>
<li class="md-nav__item">
<a href="#from-the-command-line-old-way" title="From the Command Line (Old Way)" class="md-nav__link">
From the Command Line (Old Way)
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../PandocB/" title="Pandoc: JSON to JSON" class="md-nav__link">
Pandoc: JSON to JSON
</a>
</li>
<li class="md-nav__item">
<a href="../PanfluteA/" title="Panflute: Translate" class="md-nav__link">
Panflute: Translate
</a>
</li>
<li class="md-nav__item">
<a href="../PanfluteB/" title="Panflute: Page Elements" class="md-nav__link">
Panflute: Page Elements
</a>
</li>
<li class="md-nav__item">
<a href="../PandocC/" title="Pandoc: JSON to Markdown" class="md-nav__link">
Pandoc: JSON to Markdown
</a>
</li>
<li class="md-nav__item">
<a href="../Testing/" title="Testing" class="md-nav__link">
Testing
</a>
</li>
<li class="md-nav__item">
<a href="../Links/" title="Links" class="md-nav__link">
Links
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#using-the-pandoc-api-new-way" title="Using the Pandoc API (New Way)" class="md-nav__link">
Using the Pandoc API (New Way)
</a>
</li>
<li class="md-nav__item">
<a href="#from-the-command-line-old-way" title="From the Command Line (Old Way)" class="md-nav__link">
From the Command Line (Old Way)
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content">
<article class="md-content__inner md-typeset">
<h1>Pandoc: Markdown to JSON</h1>
<p>This page covers the pandoc Markdown to JSON step.</p>
<h3 id="using-the-pandoc-api-new-way">Using the Pandoc API (New Way)<a class="headerlink" href="#using-the-pandoc-api-new-way" title="Permanent link">&para;</a></h3>
<p>(In progress)</p>
<h3 id="from-the-command-line-old-way">From the Command Line (Old Way)<a class="headerlink" href="#from-the-command-line-old-way" title="Permanent link">&para;</a></h3>
<p>We use pandoc to convert structured Markdown into JSON.
This is done using the <code>-f</code> flag to specify the input format
and the <code>-t</code> flag to specify the target format:</p>
<div class="codehilite"><pre><span></span>pandoc -t json -f gfm my_markdown_file.md
</pre></div>
<p>Here, we use <code>gfm</code> (Github-flavored markdown).</p>
<p>We can also read documents from stdin using the <code>-s</code> flag:</p>
<div class="codehilite"><pre><span></span>cat my_markdown_file.md | pandoc -t json -f gfm -s
</pre></div>
<p>The resulting JSON is ready to be parsed using a pandoc filter.</p>
<p>Note that if you wish to visualize the structure of the JSON
before processing it further, you can pipe it to <code>python -m json.tool</code>,
which nicely formats the JSON for printing and visualizing:</p>
<div class="codehilite"><pre><span></span>cat my_markdown_file.md | pandoc -t json -f gfm -s | python -m json.tool
</pre></div>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href="../Setup/" title="Setup" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div>
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Previous
</span>
Setup
</span>
</div>
</a>
<a href="../PandocB/" title="Pandoc: JSON to JSON" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Next
</span>
Pandoc: JSON to JSON
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i>
</div>
</a>
</nav>
</div>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
<div class="md-footer-copyright__highlight">
Copyright &copy; 2018 <a href="https://charlesreid1.com">Charles Reid</a>, released under the <a href="https://opensource.org/licenses/MIT">MIT License</a>.
</div>
powered by
<a href="https://www.mkdocs.org">MkDocs</a>
and
<a href="https://squidfunk.github.io/mkdocs-material/">
Material for MkDocs</a>
</div>
</div>
</div>
</footer>
</div>
<script src="../assets/javascripts/application.e72fd936.js"></script>
<script>app.initialize({version:"1.0",url:{base:".."}})</script>
<script src="../search/main.js"></script>
</body>
</html>

529
PandocB/index.html

@ -0,0 +1,529 @@
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link rel="canonical" href="https://pages.charlesreid1.com/translate-yer-docs/PandocB/">
<meta name="lang:clipboard.copy" content="Copy to clipboard">
<meta name="lang:clipboard.copied" content="Copied to clipboard">
<meta name="lang:search.language" content="en">
<meta name="lang:search.pipeline.stopwords" content="True">
<meta name="lang:search.pipeline.trimmer" content="True">
<meta name="lang:search.result.none" content="No matching documents">
<meta name="lang:search.result.one" content="1 matching document">
<meta name="lang:search.result.other" content="# matching documents">
<meta name="lang:search.tokenizer" content="[\s\-]+">
<link rel="shortcut icon" href="..">
<meta name="generator" content="mkdocs-1.0, mkdocs-material-3.0.3">
<title>Pandoc: JSON to JSON - translate-yer-docs</title>
<link rel="stylesheet" href="../assets/stylesheets/application.451f80e5.css">
<link rel="stylesheet" href="../assets/stylesheets/application-palette.22915126.css">
<meta name="theme-color" content="#3f51b5">
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script>
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Ubuntu:300,400,400i,700|Ubuntu+Mono">
<style>body,input{font-family:"Ubuntu","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Ubuntu Mono","Courier New",Courier,monospace}</style>
<link rel="stylesheet" href="../assets/fonts/material-icons.css">
<link rel="stylesheet" href="../css/custom.css">
</head>
<body dir="ltr" data-md-color-primary="indigo" data-md-color-accent="indigo">
<svg class="md-svg">
<defs>
</defs>
</svg>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
<a href="../#filtering-with-the-pandoc-api-new-way" tabindex="1" class="md-skip">
Skip to content
</a>
<header class="md-header" data-md-component="header">
<nav class="md-header-nav md-grid">
<div class="md-flex">
<div class="md-flex__cell md-flex__cell--shrink">
<a href="https://pages.charlesreid1.com/translate-yer-docs" title="translate-yer-docs" class="md-header-nav__button md-logo">
<i class="md-icon">insert_drive_file arrow_right_alt g_translate arrow_right_alt insert_drive_file</i>
</a>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--menu md-header-nav__button" for="__drawer"></label>
</div>
<div class="md-flex__cell md-flex__cell--stretch">
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title">
<span class="md-header-nav__topic">
translate-yer-docs
</span>
<span class="md-header-nav__topic">
Pandoc: JSON to JSON
</span>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--search md-header-nav__button" for="__search"></label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active">
<label class="md-icon md-search__icon" for="__search"></label>
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1">
&#xE5CD;
</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="result">
<div class="md-search-result__meta">
Type to start searching
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<div class="md-header-nav__source">
<a href="https://git.charlesreid1.com/charlesreid1/translate-yer-docs" title="Go to repository" class="md-source" data-md-source="">
<div class="md-source__repository">
translate-yer-docs
</div>
</a>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container">
<main class="md-main">
<div class="md-main__inner md-grid" data-md-component="container">
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" data-md-level="0">
<label class="md-nav__title md-nav__title--site" for="__drawer">
<a href="https://pages.charlesreid1.com/translate-yer-docs" title="translate-yer-docs" class="md-nav__button md-logo">
<i class="md-icon">insert_drive_file arrow_right_alt g_translate arrow_right_alt insert_drive_file</i>
</a>
translate-yer-docs
</label>
<div class="md-nav__source">
<a href="https://git.charlesreid1.com/charlesreid1/translate-yer-docs" title="Go to repository" class="md-source" data-md-source="">
<div class="md-source__repository">
translate-yer-docs
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." title="Home" class="md-nav__link">
Home
</a>
</li>
<li class="md-nav__item">
<a href="../Organization/" title="How This Repo is Organized" class="md-nav__link">
How This Repo is Organized
</a>
</li>
<li class="md-nav__item">
<a href="../Setup/" title="Setup" class="md-nav__link">
Setup
</a>
</li>
<li class="md-nav__item">
<a href="../PandocA/" title="Pandoc: Markdown to JSON" class="md-nav__link">
Pandoc: Markdown to JSON
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
Pandoc: JSON to JSON
</label>
<a href="./" title="Pandoc: JSON to JSON" class="md-nav__link md-nav__link--active">
Pandoc: JSON to JSON
</a>
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#filtering-with-the-pandoc-api-new-way" title="Filtering with the Pandoc API (New Way)" class="md-nav__link">
Filtering with the Pandoc API (New Way)
</a>
</li>
<li class="md-nav__item">
<a href="#filtering-from-the-command-line-old-way" title="Filtering from the Command Line (Old Way)" class="md-nav__link">
Filtering from the Command Line (Old Way)
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../PanfluteA/" title="Panflute: Translate" class="md-nav__link">
Panflute: Translate
</a>
</li>
<li class="md-nav__item">
<a href="../PanfluteB/" title="Panflute: Page Elements" class="md-nav__link">
Panflute: Page Elements
</a>
</li>
<li class="md-nav__item">
<a href="../PandocC/" title="Pandoc: JSON to Markdown" class="md-nav__link">
Pandoc: JSON to Markdown
</a>
</li>
<li class="md-nav__item">
<a href="../Testing/" title="Testing" class="md-nav__link">
Testing
</a>
</li>
<li class="md-nav__item">
<a href="../Links/" title="Links" class="md-nav__link">
Links
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#filtering-with-the-pandoc-api-new-way" title="Filtering with the Pandoc API (New Way)" class="md-nav__link">
Filtering with the Pandoc API (New Way)
</a>
</li>
<li class="md-nav__item">
<a href="#filtering-from-the-command-line-old-way" title="Filtering from the Command Line (Old Way)" class="md-nav__link">
Filtering from the Command Line (Old Way)
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content">
<article class="md-content__inner md-typeset">
<h1>Pandoc: JSON to JSON</h1>
<p>This page covers the pandoc JSON to JSON step.</p>
<p>To translate Markdown from English to Russian,
we use pandoc to parse the Markdown file and
extract the text that needs to be translated.</p>
<p>Specifically, we write a JSON-to-JSON pandoc filter
using <a href="http://scorreia.com/software/panflute/index.html">panflute</a>,
a Python library for writing pandoc filters.</p>
<h3 id="filtering-with-the-pandoc-api-new-way">Filtering with the Pandoc API (New Way)<a class="headerlink" href="#filtering-with-the-pandoc-api-new-way" title="Permanent link">&para;</a></h3>
<p>(In progress)</p>
<h3 id="filtering-from-the-command-line-old-way">Filtering from the Command Line (Old Way)<a class="headerlink" href="#filtering-from-the-command-line-old-way" title="Permanent link">&para;</a></h3>
<p>The syntax is as follows:</p>
<div class="codehilite"><pre><span></span>cat my_markdown_file.md | pandoc -t json -f gfm -s | filters/my_filter.py
</pre></div>
<p>The convention for panflute filters is that the JSON document
is passed into the panflute filter one component at a time.
If the filter does not return anything, the document element
will be used as-is in the final document. If a new document
element is returned, it is used in place of the old
document element.</p>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href="../PandocA/" title="Pandoc: Markdown to JSON" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div>
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Previous
</span>
Pandoc: Markdown to JSON
</span>
</div>
</a>
<a href="../PanfluteA/" title="Panflute: Translate" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Next
</span>
Panflute: Translate
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i>
</div>
</a>
</nav>
</div>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
<div class="md-footer-copyright__highlight">
Copyright &copy; 2018 <a href="https://charlesreid1.com">Charles Reid</a>, released under the <a href="https://opensource.org/licenses/MIT">MIT License</a>.
</div>
powered by
<a href="https://www.mkdocs.org">MkDocs</a>
and
<a href="https://squidfunk.github.io/mkdocs-material/">
Material for MkDocs</a>
</div>
</div>
</div>
</footer>
</div>
<script src="../assets/javascripts/application.e72fd936.js"></script>
<script>app.initialize({version:"1.0",url:{base:".."}})</script>
<script src="../search/main.js"></script>
</body>
</html>

500
PandocC/index.html

@ -0,0 +1,500 @@
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link rel="canonical" href="https://pages.charlesreid1.com/translate-yer-docs/PandocC/">
<meta name="lang:clipboard.copy" content="Copy to clipboard">
<meta name="lang:clipboard.copied" content="Copied to clipboard">
<meta name="lang:search.language" content="en">
<meta name="lang:search.pipeline.stopwords" content="True">
<meta name="lang:search.pipeline.trimmer" content="True">
<meta name="lang:search.result.none" content="No matching documents">
<meta name="lang:search.result.one" content="1 matching document">
<meta name="lang:search.result.other" content="# matching documents">
<meta name="lang:search.tokenizer" content="[\s\-]+">
<link rel="shortcut icon" href="..">
<meta name="generator" content="mkdocs-1.0, mkdocs-material-3.0.3">
<title>Pandoc: JSON to Markdown - translate-yer-docs</title>
<link rel="stylesheet" href="../assets/stylesheets/application.451f80e5.css">
<link rel="stylesheet" href="../assets/stylesheets/application-palette.22915126.css">
<meta name="theme-color" content="#3f51b5">
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script>
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Ubuntu:300,400,400i,700|Ubuntu+Mono">
<style>body,input{font-family:"Ubuntu","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Ubuntu Mono","Courier New",Courier,monospace}</style>
<link rel="stylesheet" href="../assets/fonts/material-icons.css">
<link rel="stylesheet" href="../css/custom.css">
</head>
<body dir="ltr" data-md-color-primary="indigo" data-md-color-accent="indigo">
<svg class="md-svg">
<defs>
</defs>
</svg>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
<a href="../#pandoc-parser-json-to-markdown-parser" tabindex="1" class="md-skip">
Skip to content
</a>
<header class="md-header" data-md-component="header">
<nav class="md-header-nav md-grid">
<div class="md-flex">
<div class="md-flex__cell md-flex__cell--shrink">
<a href="https://pages.charlesreid1.com/translate-yer-docs" title="translate-yer-docs" class="md-header-nav__button md-logo">
<i class="md-icon">insert_drive_file arrow_right_alt g_translate arrow_right_alt insert_drive_file</i>
</a>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--menu md-header-nav__button" for="__drawer"></label>
</div>
<div class="md-flex__cell md-flex__cell--stretch">
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title">
<span class="md-header-nav__topic">
translate-yer-docs
</span>
<span class="md-header-nav__topic">
Pandoc: JSON to Markdown
</span>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--search md-header-nav__button" for="__search"></label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active">
<label class="md-icon md-search__icon" for="__search"></label>
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1">
&#xE5CD;
</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="result">
<div class="md-search-result__meta">
Type to start searching
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<div class="md-header-nav__source">
<a href="https://git.charlesreid1.com/charlesreid1/translate-yer-docs" title="Go to repository" class="md-source" data-md-source="">
<div class="md-source__repository">
translate-yer-docs
</div>
</a>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container">
<main class="md-main">
<div class="md-main__inner md-grid" data-md-component="container">
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" data-md-level="0">
<label class="md-nav__title md-nav__title--site" for="__drawer">
<a href="https://pages.charlesreid1.com/translate-yer-docs" title="translate-yer-docs" class="md-nav__button md-logo">
<i class="md-icon">insert_drive_file arrow_right_alt g_translate arrow_right_alt insert_drive_file</i>
</a>
translate-yer-docs
</label>
<div class="md-nav__source">
<a href="https://git.charlesreid1.com/charlesreid1/translate-yer-docs" title="Go to repository" class="md-source" data-md-source="">
<div class="md-source__repository">
translate-yer-docs
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." title="Home" class="md-nav__link">
Home
</a>
</li>
<li class="md-nav__item">
<a href="../Organization/" title="How This Repo is Organized" class="md-nav__link">
How This Repo is Organized
</a>
</li>
<li class="md-nav__item">
<a href="../Setup/" title="Setup" class="md-nav__link">
Setup
</a>
</li>
<li class="md-nav__item">
<a href="../PandocA/" title="Pandoc: Markdown to JSON" class="md-nav__link">
Pandoc: Markdown to JSON
</a>
</li>
<li class="md-nav__item">
<a href="../PandocB/" title="Pandoc: JSON to JSON" class="md-nav__link">
Pandoc: JSON to JSON
</a>
</li>
<li class="md-nav__item">
<a href="../PanfluteA/" title="Panflute: Translate" class="md-nav__link">
Panflute: Translate
</a>
</li>
<li class="md-nav__item">
<a href="../PanfluteB/" title="Panflute: Page Elements" class="md-nav__link">
Panflute: Page Elements
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
Pandoc: JSON to Markdown
</label>
<a href="./" title="Pandoc: JSON to Markdown" class="md-nav__link md-nav__link--active">
Pandoc: JSON to Markdown
</a>
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#pandoc-parser-json-to-markdown-parser" title="Pandoc Parser: JSON-to-Markdown Parser" class="md-nav__link">
Pandoc Parser: JSON-to-Markdown Parser
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../Testing/" title="Testing" class="md-nav__link">
Testing
</a>
</li>
<li class="md-nav__item">
<a href="../Links/" title="Links" class="md-nav__link">
Links
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#pandoc-parser-json-to-markdown-parser" title="Pandoc Parser: JSON-to-Markdown Parser" class="md-nav__link">
Pandoc Parser: JSON-to-Markdown Parser
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content">
<article class="md-content__inner md-typeset">
<h1>Pandoc: JSON to Markdown</h1>
<h2 id="pandoc-parser-json-to-markdown-parser">Pandoc Parser: JSON-to-Markdown Parser<a class="headerlink" href="#pandoc-parser-json-to-markdown-parser" title="Permanent link">&para;</a></h2>
<p>To return everything back into Markdown, the last step of the pipeline
is to add another call to pandoc, but with the formats reversed, so that
it will turn JSON back into Markdown:</p>
<div class="codehilite"><pre><span></span>cat shepherd.md | pandoc -t json -f gfm -s | ./panflute_rooskie.py | pandoc -f json -t gfm -s &gt; shepherd_ru.md
</pre></div>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href="../PanfluteB/" title="Panflute: Page Elements" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div>
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Previous
</span>
Panflute: Page Elements
</span>
</div>
</a>
<a href="../Testing/" title="Testing" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Next
</span>
Testing
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i>
</div>
</a>
</nav>
</div>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
<div class="md-footer-copyright__highlight">
Copyright &copy; 2018 <a href="https://charlesreid1.com">Charles Reid</a>, released under the <a href="https://opensource.org/licenses/MIT">MIT License</a>.
</div>
powered by
<a href="https://www.mkdocs.org">MkDocs</a>
and
<a href="https://squidfunk.github.io/mkdocs-material/">
Material for MkDocs</a>
</div>
</div>
</div>
</footer>
</div>
<script src="../assets/javascripts/application.e72fd936.js"></script>
<script>app.initialize({version:"1.0",url:{base:".."}})</script>
<script src="../search/main.js"></script>
</body>
</html>

543
PanfluteA/index.html

@ -0,0 +1,543 @@
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link rel="canonical" href="https://pages.charlesreid1.com/translate-yer-docs/PanfluteA/">
<meta name="lang:clipboard.copy" content="Copy to clipboard">
<meta name="lang:clipboard.copied" content="Copied to clipboard">
<meta name="lang:search.language" content="en">
<meta name="lang:search.pipeline.stopwords" content="True">
<meta name="lang:search.pipeline.trimmer" content="True">
<meta name="lang:search.result.none" content="No matching documents">
<meta name="lang:search.result.one" content="1 matching document">
<meta name="lang:search.result.other" content="# matching documents">
<meta name="lang:search.tokenizer" content="[\s\-]+">
<link rel="shortcut icon" href="..">
<meta name="generator" content="mkdocs-1.0, mkdocs-material-3.0.3">
<title>Panflute: Translate - translate-yer-docs</title>
<link rel="stylesheet" href="../assets/stylesheets/application.451f80e5.css">
<link rel="stylesheet" href="../assets/stylesheets/application-palette.22915126.css">
<meta name="theme-color" content="#3f51b5">
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script>
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Ubuntu:300,400,400i,700|Ubuntu+Mono">
<style>body,input{font-family:"Ubuntu","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Ubuntu Mono","Courier New",Courier,monospace}</style>
<link rel="stylesheet" href="../assets/fonts/material-icons.css">
<link rel="stylesheet" href="../css/custom.css">
</head>
<body dir="ltr" data-md-color-primary="indigo" data-md-color-accent="indigo">
<svg class="md-svg">
<defs>
</defs>
</svg>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
<header class="md-header" data-md-component="header">
<nav class="md-header-nav md-grid">
<div class="md-flex">
<div class="md-flex__cell md-flex__cell--shrink">
<a href="https://pages.charlesreid1.com/translate-yer-docs" title="translate-yer-docs" class="md-header-nav__button md-logo">
<i class="md-icon">insert_drive_file arrow_right_alt g_translate arrow_right_alt insert_drive_file</i>
</a>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--menu md-header-nav__button" for="__drawer"></label>
</div>
<div class="md-flex__cell md-flex__cell--stretch">
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title">
<span class="md-header-nav__topic">
translate-yer-docs
</span>
<span class="md-header-nav__topic">
Panflute: Translate
</span>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--search md-header-nav__button" for="__search"></label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active">
<label class="md-icon md-search__icon" for="__search"></label>
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1">
&#xE5CD;
</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="result">
<div class="md-search-result__meta">
Type to start searching
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<div class="md-header-nav__source">
<a href="https://git.charlesreid1.com/charlesreid1/translate-yer-docs" title="Go to repository" class="md-source" data-md-source="">
<div class="md-source__repository">
translate-yer-docs
</div>
</a>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container">
<main class="md-main">
<div class="md-main__inner md-grid" data-md-component="container">
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" data-md-level="0">
<label class="md-nav__title md-nav__title--site" for="__drawer">
<a href="https://pages.charlesreid1.com/translate-yer-docs" title="translate-yer-docs" class="md-nav__button md-logo">
<i class="md-icon">insert_drive_file arrow_right_alt g_translate arrow_right_alt insert_drive_file</i>
</a>
translate-yer-docs
</label>
<div class="md-nav__source">
<a href="https://git.charlesreid1.com/charlesreid1/translate-yer-docs" title="Go to repository" class="md-source" data-md-source="">
<div class="md-source__repository">
translate-yer-docs
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." title="Home" class="md-nav__link">
Home
</a>
</li>
<li class="md-nav__item">
<a href="../Organization/" title="How This Repo is Organized" class="md-nav__link">
How This Repo is Organized
</a>
</li>
<li class="md-nav__item">
<a href="../Setup/" title="Setup" class="md-nav__link">
Setup
</a>
</li>
<li class="md-nav__item">
<a href="../PandocA/" title="Pandoc: Markdown to JSON" class="md-nav__link">
Pandoc: Markdown to JSON
</a>
</li>
<li class="md-nav__item">
<a href="../PandocB/" title="Pandoc: JSON to JSON" class="md-nav__link">
Pandoc: JSON to JSON
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<a href="./" title="Panflute: Translate" class="md-nav__link md-nav__link--active">
Panflute: Translate
</a>
</li>
<li class="md-nav__item">
<a href="../PanfluteB/" title="Panflute: Page Elements" class="md-nav__link">
Panflute: Page Elements
</a>
</li>
<li class="md-nav__item">
<a href="../PandocC/" title="Pandoc: JSON to Markdown" class="md-nav__link">
Pandoc: JSON to Markdown
</a>
</li>
<li class="md-nav__item">
<a href="../Testing/" title="Testing" class="md-nav__link">
Testing
</a>
</li>
<li class="md-nav__item">
<a href="../Links/" title="Links" class="md-nav__link">
Links
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content">
<article class="md-content__inner md-typeset">
<h1>Panflute: Translate</h1>
<p>To translate Markdown text to Russian, we want to look for
Para (paragraph) components, and extract the text from
each paragraph as a string.</p>
<div class="codehilite"><pre><span></span>cat shepherd.md | pandoc -t json -f gfm -s | filters/translate.py
</pre></div>
<p>The <code>translate.py</code> panflute filter determines what text to translate
and calls the Google Cloud Translate API to do the translating.</p>
<p>We use the Google Cloud Translate API using a Python client library
that they provide, rather than fussing with assembling our own
payloads and using the <code>requests</code> library.</p>
<p><strong><code>filters/translate.py</code>:</strong></p>
<div class="codehilite"><pre><span></span><span class="kn">from</span> <span class="nn">panflute</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">google.cloud</span> <span class="kn">import</span> <span class="n">translate</span>
<span class="k">def</span> <span class="nf">translate_document</span><span class="p">(</span><span class="n">elem</span><span class="p">,</span> <span class="n">doc</span><span class="p">):</span>
<span class="o">...</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">(</span><span class="n">doc</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
<span class="k">return</span> <span class="n">run_filter</span><span class="p">(</span><span class="n">translate_document</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="n">doc</span><span class="p">)</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&quot;__main__&quot;</span><span class="p">:</span>
<span class="n">main</span><span class="p">()</span>
</pre></div>
<p>When we run this, it passes each document element through
<code>translate_document()</code>. </p>
<p>Two things we wnat to do up front:</p>
<ul>
<li>
<p>Extract links (these are problematic for translation,
we deal with them by removing the link from the inline text
and including a list at the bottom of the document of
the (translated) original link text, plus the link itself.</p>
</li>
<li>
<p>Search for paragraphs of text, or headings, and replace text
with a translation.</p>
</li>
</ul>
<p>To do the first, we define a function called <code>strip_links()</code>,
which will strip out all the links and add them to the bottom
of the document (more on this in a minute).</p>
<p>We pass this function to <code>elem.walk()</code> to apply it to every
element underneath the current element. This means we can
write the <code>strip_links()</code> function in a similar way to the
<code>translate_document()</code> function: look for specific types of
elements, and modify them accordingly.</p>
<div class="codehilite"><pre><span></span><span class="k">def</span> <span class="nf">translate_document</span><span class="p">(</span><span class="n">elem</span><span class="p">,</span> <span class="n">doc</span><span class="p">):</span>
<span class="c1"># Walk it and look for links first</span>
<span class="n">elem</span><span class="o">.</span><span class="n">walk</span><span class="p">(</span><span class="n">strip_links</span><span class="p">)</span>
<span class="o">...</span>
</pre></div>
<p>Another thing we want to do is translate paragraph text from
Russian to English. We use stringify to turn a list of Str
and Space objects into a regular string:</p>
<div class="codehilite"><pre><span></span><span class="k">def</span> <span class="nf">translate_document</span><span class="p">(</span><span class="n">elem</span><span class="p">,</span> <span class="n">doc</span><span class="p">):</span>
<span class="c1"># Walk it and look for links first</span>
<span class="n">elem</span><span class="o">.</span><span class="n">walk</span><span class="p">(</span><span class="n">strip_links</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">elem</span><span class="p">)</span><span class="o">==</span><span class="n">Para</span><span class="p">:</span>
<span class="n">english</span> <span class="o">=</span> <span class="n">stringify</span><span class="p">(</span><span class="n">doc</span><span class="p">)</span>
<span class="n">translation</span> <span class="o">=</span> <span class="n">english_to_X</span><span class="p">(</span><span class="n">english</span><span class="p">)</span>
<span class="o">...</span>
</pre></div>
<p>The <code>english_to_X()</code> function (more on this shortly) will use
the Google Cloud Translate API to translate English to our language of choice.
This requires an API key with Google Cloud (see <a href="../Setup/">Setup</a>).</p>
<p>The translate function will return unicode text. This must be turned back into
structured text that pandoc understands, so we have to wrap words in Str()
and replace spaces with Space objects.</p>
<p>To do this easily with a string in panflute, use <code>convert_text()</code>:</p>
<div class="codehilite"><pre><span></span> english = stringify(elem)
rooskie = english_to_russian(english)
new_elems = convert_text(rooskie,input_format=&#39;markdown&#39;)
return new_elems
</pre></div>
<p>To get Google Cloud Translate API working properly,
you must export an environment variable <code>$GOOGLE_APPLICATION_CREDENTIALS</code>
that points to a JSON file with your API keys
EACH TIME YOU RUN THE SCRIPT!!!</p>
<div class="codehilite"><pre><span></span>############################################
############################################
############## ##############
############## NOTE ##############
############## ##############
##
## This step is required for the translate
## API calls to work. Don&#39;t leave this out.
##
############################################
############################################
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/project-key-00000.json
</pre></div>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href="../PandocB/" title="Pandoc: JSON to JSON" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div>
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Previous
</span>
Pandoc: JSON to JSON
</span>
</div>
</a>
<a href="../PanfluteB/" title="Panflute: Page Elements" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Next
</span>
Panflute: Page Elements
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i>
</div>
</a>
</nav>
</div>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
<div class="md-footer-copyright__highlight">
Copyright &copy; 2018 <a href="https://charlesreid1.com">Charles Reid</a>, released under the <a href="https://opensource.org/licenses/MIT">MIT License</a>.
</div>
powered by
<a href="https://www.mkdocs.org">MkDocs</a>
and
<a href="https://squidfunk.github.io/mkdocs-material/">
Material for MkDocs</a>
</div>
</div>
</div>
</footer>
</div>
<script src="../assets/javascripts/application.e72fd936.js"></script>
<script>app.initialize({version:"1.0",url:{base:".."}})</script>
<script src="../search/main.js"></script>
</body>
</html>

609
PanfluteB/index.html

@ -0,0 +1,609 @@
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link rel="canonical" href="https://pages.charlesreid1.com/translate-yer-docs/PanfluteB/">
<meta name="lang:clipboard.copy" content="Copy to clipboard">
<meta name="lang:clipboard.copied" content="Copied to clipboard">
<meta name="lang:search.language" content="en">
<meta name="lang:search.pipeline.stopwords" content="True">
<meta name="lang:search.pipeline.trimmer" content="True">
<meta name="lang:search.result.none" content="No matching documents">
<meta name="lang:search.result.one" content="1 matching document">
<meta name="lang:search.result.other" content="# matching documents">
<meta name="lang:search.tokenizer" content="[\s\-]+">
<link rel="shortcut icon" href="..">
<meta name="generator" content="mkdocs-1.0, mkdocs-material-3.0.3">
<title>Panflute: Page Elements - translate-yer-docs</title>
<link rel="stylesheet" href="../assets/stylesheets/application.451f80e5.css">
<link rel="stylesheet" href="../assets/stylesheets/application-palette.22915126.css">
<meta name="theme-color" content="#3f51b5">
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script>
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Ubuntu:300,400,400i,700|Ubuntu+Mono">
<style>body,input{font-family:"Ubuntu","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Ubuntu Mono","Courier New",Courier,monospace}</style>
<link rel="stylesheet" href="../assets/fonts/material-icons.css">
<link rel="stylesheet" href="../css/custom.css">
</head>
<body dir="ltr" data-md-color-primary="indigo" data-md-color-accent="indigo">
<svg class="md-svg">
<defs>
</defs>
</svg>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
<a href="../#links" tabindex="1" class="md-skip">
Skip to content
</a>
<header class="md-header" data-md-component="header">
<nav class="md-header-nav md-grid">
<div class="md-flex">
<div class="md-flex__cell md-flex__cell--shrink">
<a href="https://pages.charlesreid1.com/translate-yer-docs" title="translate-yer-docs" class="md-header-nav__button md-logo">
<i class="md-icon">insert_drive_file arrow_right_alt g_translate arrow_right_alt insert_drive_file</i>
</a>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--menu md-header-nav__button" for="__drawer"></label>
</div>
<div class="md-flex__cell md-flex__cell--stretch">
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title">
<span class="md-header-nav__topic">
translate-yer-docs
</span>
<span class="md-header-nav__topic">
Panflute: Page Elements
</span>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--search md-header-nav__button" for="__search"></label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active">
<label class="md-icon md-search__icon" for="__search"></label>
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1">
&#xE5CD;
</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="result">
<div class="md-search-result__meta">
Type to start searching
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<div class="md-header-nav__source">
<a href="https://git.charlesreid1.com/charlesreid1/translate-yer-docs" title="Go to repository" class="md-source" data-md-source="">
<div class="md-source__repository">
translate-yer-docs
</div>
</a>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container">
<main class="md-main">
<div class="md-main__inner md-grid" data-md-component="container">
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" data-md-level="0">
<label class="md-nav__title md-nav__title--site" for="__drawer">
<a href="https://pages.charlesreid1.com/translate-yer-docs" title="translate-yer-docs" class="md-nav__button md-logo">
<i class="md-icon">insert_drive_file arrow_right_alt g_translate arrow_right_alt insert_drive_file</i>
</a>
translate-yer-docs
</label>
<div class="md-nav__source">
<a href="https://git.charlesreid1.com/charlesreid1/translate-yer-docs" title="Go to repository" class="md-source" data-md-source="">
<div class="md-source__repository">
translate-yer-docs
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." title="Home" class="md-nav__link">
Home
</a>
</li>
<li class="md-nav__item">
<a href="../Organization/" title="How This Repo is Organized" class="md-nav__link">
How This Repo is Organized
</a>
</li>
<li class="md-nav__item">
<a href="../Setup/" title="Setup" class="md-nav__link">
Setup
</a>
</li>
<li class="md-nav__item">
<a href="../PandocA/" title="Pandoc: Markdown to JSON" class="md-nav__link">
Pandoc: Markdown to JSON
</a>
</li>
<li class="md-nav__item">
<a href="../PandocB/" title="Pandoc: JSON to JSON" class="md-nav__link">
Pandoc: JSON to JSON
</a>
</li>
<li class="md-nav__item">
<a href="../PanfluteA/" title="Panflute: Translate" class="md-nav__link">
Panflute: Translate
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
Panflute: Page Elements
</label>
<a href="./" title="Panflute: Page Elements" class="md-nav__link md-nav__link--active">
Panflute: Page Elements
</a>
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#links" title="Links" class="md-nav__link">
Links
</a>
</li>
<li class="md-nav__item">
<a href="#lists" title="Lists" class="md-nav__link">
Lists
</a>
</li>
<li class="md-nav__item">
<a href="#images" title="Images" class="md-nav__link">
Images
</a>
</li>
<li class="md-nav__item">
<a href="#headers" title="Headers" class="md-nav__link">
Headers
</a>
</li>
<li class="md-nav__item">
<a href="#links_1" title="Links" class="md-nav__link">
Links
</a>
</li>
<li class="md-nav__item">
<a href="#panflute-filter" title="Panflute Filter" class="md-nav__link">
Panflute Filter
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../PandocC/" title="Pandoc: JSON to Markdown" class="md-nav__link">
Pandoc: JSON to Markdown
</a>
</li>
<li class="md-nav__item">
<a href="../Testing/" title="Testing" class="md-nav__link">
Testing
</a>
</li>
<li class="md-nav__item">
<a href="../Links/" title="Links" class="md-nav__link">
Links
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#links" title="Links" class="md-nav__link">
Links
</a>
</li>
<li class="md-nav__item">
<a href="#lists" title="Lists" class="md-nav__link">
Lists
</a>
</li>
<li class="md-nav__item">
<a href="#images" title="Images" class="md-nav__link">
Images
</a>
</li>
<li class="md-nav__item">
<a href="#headers" title="Headers" class="md-nav__link">
Headers
</a>
</li>
<li class="md-nav__item">
<a href="#links_1" title="Links" class="md-nav__link">
Links
</a>
</li>
<li class="md-nav__item">
<a href="#panflute-filter" title="Panflute Filter" class="md-nav__link">
Panflute Filter
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content">
<article class="md-content__inner md-typeset">
<h1>Panflute: Page Elements</h1>
<p>One of the pain points of translating a document is figuring out
what to do with page elements.</p>
<h2 id="links">Links<a class="headerlink" href="#links" title="Permanent link">&para;</a></h2>
<h2 id="lists">Lists<a class="headerlink" href="#lists" title="Permanent link">&para;</a></h2>
<h2 id="images">Images<a class="headerlink" href="#images" title="Permanent link">&para;</a></h2>
<h2 id="headers">Headers<a class="headerlink" href="#headers" title="Permanent link">&para;</a></h2>
<h2 id="links_1">Links<a class="headerlink" href="#links_1" title="Permanent link">&para;</a></h2>
<p>Take hyperlinks as an example. Here's how we deal with it:</p>
<p>We have a <code>prepare()</code> method in our panflute filter that is run
before the document filter is applied, and a <code>finalize()</code> method
that is run after the document filter is applied.</p>
<p>The prepare method initializes an empty list to hold links.
As we parse each section of the document, we look for
links, and when we find a link, we add the link to a list.</p>
<p>When the text is translated, links are stripped out and
the original link text becomes plain text again.
Rather than try and determine which words in the
translation map to the original link text,
we simply aggregate the links at the bottom of the
document. Each link includes a translation of the
original link text that is a link to the original link.</p>
<h2 id="panflute-filter">Panflute Filter<a class="headerlink" href="#panflute-filter" title="Permanent link">&para;</a></h2>
<p>Let's cover a bit more of the panflute magic that makes
all of that happen.</p>
<p>This relies on two additional methods for the filter:
<code>prepare()</code> and <code>finalize()</code>.</p>
<p>The prepare method just creates an empty list that will
be used to store all of the link elements in the document:</p>
<div class="codehilite"><pre><span></span>def prepare(doc):
doc.linklist = []
</pre></div>
<p>We call the <code>elem.walk()</code> method on each element of the
document, so we have a chance to see each element and
determine if it is a link. If it is, we keep it simple
and just save the entire element:</p>
<div class="codehilite"><pre><span></span>def strip_links(elem,doc):
&quot;&quot;&quot;
Each link will be stripped in the translation process.
Save them for the end.
&quot;&quot;&quot;
if isinstance(elem,Link):
doc.linklist.append(elem)
</pre></div>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href="../PanfluteA/" title="Panflute: Translate" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div>
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Previous
</span>
Panflute: Translate
</span>
</div>
</a>
<a href="../PandocC/" title="Pandoc: JSON to Markdown" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Next
</span>
Pandoc: JSON to Markdown
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i>
</div>
</a>
</nav>
</div>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
<div class="md-footer-copyright__highlight">
Copyright &copy; 2018 <a href="https://charlesreid1.com">Charles Reid</a>, released under the <a href="https://opensource.org/licenses/MIT">MIT License</a>.
</div>
powered by
<a href="https://www.mkdocs.org">MkDocs</a>
and
<a href="https://squidfunk.github.io/mkdocs-material/">
Material for MkDocs</a>
</div>
</div>
</div>
</footer>
</div>
<script src="../assets/javascripts/application.e72fd936.js"></script>
<script>app.initialize({version:"1.0",url:{base:".."}})</script>
<script src="../search/main.js"></script>
</body>
</html>

14
README.md

@ -1,14 +0,0 @@
# translate-the-docs
A pandoc tool to translate your Markdown docs.
See documentation here: [https://pages.charlesreid1.com/translate-yer-docs/](https://pages.charlesreid1.com/translate-yer-docs/)
Source code here: [https://git.charlesreid1.com/charlesreid1/translate-yer-docs](https://git.charlesreid1.com/charlesreid1/translate-yer-docs)
Also on Github: [https://github.com/charlesreid1/translate-yer-docs](https://github.com/charlesreid1/translate-yer-docs)
## Installation
requires pandoc, panflute, and gcloud command line tool.

611
Setup/index.html

@ -0,0 +1,611 @@
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link rel="canonical" href="https://pages.charlesreid1.com/translate-yer-docs/Setup/">
<meta name="lang:clipboard.copy" content="Copy to clipboard">
<meta name="lang:clipboard.copied" content="Copied to clipboard">
<meta name="lang:search.language" content="en">
<meta name="lang:search.pipeline.stopwords" content="True">
<meta name="lang:search.pipeline.trimmer" content="True">
<meta name="lang:search.result.none" content="No matching documents">
<meta name="lang:search.result.one" content="1 matching document">
<meta name="lang:search.result.other" content="# matching documents">
<meta name="lang:search.tokenizer" content="[\s\-]+">
<link rel="shortcut icon" href="..">
<meta name="generator" content="mkdocs-1.0, mkdocs-material-3.0.3">
<title>Setup - translate-yer-docs</title>
<link rel="stylesheet" href="../assets/stylesheets/application.451f80e5.css">
<link rel="stylesheet" href="../assets/stylesheets/application-palette.22915126.css">
<meta name="theme-color" content="#3f51b5">
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script>
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Ubuntu:300,400,400i,700|Ubuntu+Mono">
<style>body,input{font-family:"Ubuntu","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Ubuntu Mono","Courier New",Courier,monospace}</style>
<link rel="stylesheet" href="../assets/fonts/material-icons.css">
<link rel="stylesheet" href="../css/custom.css">
</head>
<body dir="ltr" data-md-color-primary="indigo" data-md-color-accent="indigo">
<svg class="md-svg">
<defs>
</defs>
</svg>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
<a href="../#setup" tabindex="1" class="md-skip">
Skip to content
</a>
<header class="md-header" data-md-component="header">
<nav class="md-header-nav md-grid">
<div class="md-flex">
<div class="md-flex__cell md-flex__cell--shrink">
<a href="https://pages.charlesreid1.com/translate-yer-docs" title="translate-yer-docs" class="md-header-nav__button md-logo">
<i class="md-icon">insert_drive_file arrow_right_alt g_translate arrow_right_alt insert_drive_file</i>
</a>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--menu md-header-nav__button" for="__drawer"></label>
</div>
<div class="md-flex__cell md-flex__cell--stretch">
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title">
<span class="md-header-nav__topic">
translate-yer-docs
</span>
<span class="md-header-nav__topic">
Setup
</span>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--search md-header-nav__button" for="__search"></label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active">
<label class="md-icon md-search__icon" for="__search"></label>
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1">
&#xE5CD;
</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="result">
<div class="md-search-result__meta">
Type to start searching
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<div class="md-header-nav__source">
<a href="https://git.charlesreid1.com/charlesreid1/translate-yer-docs" title="Go to repository" class="md-source" data-md-source="">
<div class="md-source__repository">
translate-yer-docs
</div>
</a>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container">
<main class="md-main">
<div class="md-main__inner md-grid" data-md-component="container">
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" data-md-level="0">
<label class="md-nav__title md-nav__title--site" for="__drawer">
<a href="https://pages.charlesreid1.com/translate-yer-docs" title="translate-yer-docs" class="md-nav__button md-logo">
<i class="md-icon">insert_drive_file arrow_right_alt g_translate arrow_right_alt insert_drive_file</i>
</a>
translate-yer-docs
</label>
<div class="md-nav__source">
<a href="https://git.charlesreid1.com/charlesreid1/translate-yer-docs" title="Go to repository" class="md-source" data-md-source="">
<div class="md-source__repository">
translate-yer-docs
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." title="Home" class="md-nav__link">
Home
</a>
</li>
<li class="md-nav__item">
<a href="../Organization/" title="How This Repo is Organized" class="md-nav__link">
How This Repo is Organized
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
Setup
</label>
<a href="./" title="Setup" class="md-nav__link md-nav__link--active">
Setup
</a>
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#create-google-cloud-account" title="Create Google Cloud Account" class="md-nav__link">
Create Google Cloud Account
</a>
</li>
<li class="md-nav__item">
<a href="#enable-api" title="Enable API" class="md-nav__link">
Enable API
</a>
</li>
<li class="md-nav__item">
<a href="#set-up-command-line-tool" title="Set Up Command Line Tool" class="md-nav__link">
Set Up Command Line Tool
</a>
</li>
<li class="md-nav__item">
<a href="#test-command-line-tool" title="Test Command Line Tool" class="md-nav__link">
Test Command Line Tool
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../PandocA/" title="Pandoc: Markdown to JSON" class="md-nav__link">
Pandoc: Markdown to JSON
</a>
</li>
<li class="md-nav__item">
<a href="../PandocB/" title="Pandoc: JSON to JSON" class="md-nav__link">
Pandoc: JSON to JSON
</a>
</li>
<li class="md-nav__item">
<a href="../PanfluteA/" title="Panflute: Translate" class="md-nav__link">
Panflute: Translate
</a>
</li>
<li class="md-nav__item">
<a href="../PanfluteB/" title="Panflute: Page Elements" class="md-nav__link">
Panflute: Page Elements
</a>
</li>
<li class="md-nav__item">
<a href="../PandocC/" title="Pandoc: JSON to Markdown" class="md-nav__link">
Pandoc: JSON to Markdown
</a>
</li>
<li class="md-nav__item">
<a href="../Testing/" title="Testing" class="md-nav__link">
Testing
</a>
</li>
<li class="md-nav__item">
<a href="../Links/" title="Links" class="md-nav__link">
Links
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#create-google-cloud-account" title="Create Google Cloud Account" class="md-nav__link">
Create Google Cloud Account
</a>
</li>
<li class="md-nav__item">
<a href="#enable-api" title="Enable API" class="md-nav__link">
Enable API
</a>
</li>
<li class="md-nav__item">
<a href="#set-up-command-line-tool" title="Set Up Command Line Tool" class="md-nav__link">
Set Up Command Line Tool
</a>
</li>
<li class="md-nav__item">
<a href="#test-command-line-tool" title="Test Command Line Tool" class="md-nav__link">
Test Command Line Tool
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content">
<article class="md-content__inner md-typeset">
<h1 id="setup">Setup<a class="headerlink" href="#setup" title="Permanent link">&para;</a></h1>
<p>Rundown of necessary setup steps:</p>
<ul>
<li>Create Google Cloud account</li>
<li>Enable Googe Cloud Translate API</li>
<li>Set up gcloud command line tool</li>
<li>Test gcloud command line tool</li>
</ul>
<h2 id="create-google-cloud-account">Create Google Cloud Account<a class="headerlink" href="#create-google-cloud-account" title="Permanent link">&para;</a></h2>
<p>Creating a Google Cloud account requires a credit card.</p>
<p>Obtaining a credit card is generally straightforward,
and simply involves burrowing your way into the corporate
bureaucracy by getting a job in an IT department. </p>
<p>Academic institutions provide an optimal environment
for obtaining a credit card to carry out sanctioned
bot flock activities.</p>
<h2 id="enable-api">Enable API<a class="headerlink" href="#enable-api" title="Permanent link">&para;</a></h2>
<p>Enable the Google Cloud Translate API <a href="https://cloud.google.com/translate/docs/quickstart">here</a>.</p>
<h2 id="set-up-command-line-tool">Set Up Command Line Tool<a class="headerlink" href="#set-up-command-line-tool" title="Permanent link">&para;</a></h2>
<p>The Google Cloud SDK provides a command line tool
that has utilities for interacting with the APIs.</p>
<p>The prior step will give you a JSON key file.
Associate this with the command line tool using
the <code>auth activate-service-account</code> verb:</p>
<div class="codehilite"><pre><span></span>gcloud auth activate-service-account --key-file=[PATH]
</pre></div>
<p>Set this permanently by setting the location of the key file
using an environment variable:</p>
<div class="codehilite"><pre><span></span>export GOOGLE_APPLICATION_CREDENTIALS=${PWD}/krash.json
</pre></div>
<h2 id="test-command-line-tool">Test Command Line Tool<a class="headerlink" href="#test-command-line-tool" title="Permanent link">&para;</a></h2>
<p>The API endpoint we will use is:</p>
<div class="codehilite"><pre><span></span>https://translation.googleapis.com/language/translate/v2
</pre></div>
<p>To call this endpoint, we have to include
a payload containing our API key, which we
obtained earlier when we enabled the API.
The <code>gcloud</code> tool provides a way to insert
credentials easily:</p>
<p>The command </p>
<div class="codehilite"><pre><span></span>curl -s -X POST -H &quot;Content-Type: application/json&quot; \
-H &quot;Authorization: Bearer &quot;$(gcloud auth print-access-token) \
--data &quot;{
&#39;q&#39;:&#39;Rainbow mind machine is extendable to keep bots from becoming boring. There are only two components to extend. These two components have a simple and clear order of function calls. Rainbow mind machine uses sensible defaults.&#39;,
&#39;source&#39;: &#39;en&#39;,
&#39;target&#39;: &#39;ru&#39;,
&#39;format&#39;: &#39;text&#39;
}&quot; &quot;https://translation.googleapis.com/language/translate/v2&quot;
</pre></div>
<p>should yield the result:</p>
<div class="codehilite"><pre><span></span>{
&quot;data&quot;: {
&quot;translations&quot;: [
{
&quot;translatedText&quot;: &quot;Радужная машина разума расширяема, чтобы боты не становились скучными. Расширяются только два компонента. Эти два компонента имеют простой и понятный порядок вызовов функций. Машина Rainbow mind использует разумные значения по умолчанию.&quot;
}
]
}
}
</pre></div>
<p>So far, so good.</p>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href="../Organization/" title="How This Repo is Organized" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div>
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Previous
</span>
How This Repo is Organized
</span>
</div>
</a>
<a href="../PandocA/" title="Pandoc: Markdown to JSON" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Next
</span>
Pandoc: Markdown to JSON
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i>
</div>
</a>
</nav>
</div>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
<div class="md-footer-copyright__highlight">
Copyright &copy; 2018 <a href="https://charlesreid1.com">Charles Reid</a>, released under the <a href="https://opensource.org/licenses/MIT">MIT License</a>.
</div>
powered by
<a href="https://www.mkdocs.org">MkDocs</a>
and
<a href="https://squidfunk.github.io/mkdocs-material/">
Material for MkDocs</a>
</div>
</div>
</div>
</footer>
</div>
<script src="../assets/javascripts/application.e72fd936.js"></script>
<script>app.initialize({version:"1.0",url:{base:".."}})</script>
<script src="../search/main.js"></script>
</body>
</html>

500
Testing/index.html

@ -0,0 +1,500 @@
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link rel="canonical" href="https://pages.charlesreid1.com/translate-yer-docs/Testing/">
<meta name="lang:clipboard.copy" content="Copy to clipboard">
<meta name="lang:clipboard.copied" content="Copied to clipboard">
<meta name="lang:search.language" content="en">
<meta name="lang:search.pipeline.stopwords" content="True">
<meta name="lang:search.pipeline.trimmer" content="True">
<meta name="lang:search.result.none" content="No matching documents">
<meta name="lang:search.result.one" content="1 matching document">
<meta name="lang:search.result.other" content="# matching documents">
<meta name="lang:search.tokenizer" content="[\s\-]+">
<link rel="shortcut icon" href="..">
<meta name="generator" content="mkdocs-1.0, mkdocs-material-3.0.3">
<title>Testing - translate-yer-docs</title>
<link rel="stylesheet" href="../assets/stylesheets/application.451f80e5.css">
<link rel="stylesheet" href="../assets/stylesheets/application-palette.22915126.css">
<meta name="theme-color" content="#3f51b5">
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script>
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Ubuntu:300,400,400i,700|Ubuntu+Mono">
<style>body,input{font-family:"Ubuntu","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Ubuntu Mono","Courier New",Courier,monospace}</style>
<link rel="stylesheet" href="../assets/fonts/material-icons.css">
<link rel="stylesheet" href="../css/custom.css">
</head>
<body dir="ltr" data-md-color-primary="indigo" data-md-color-accent="indigo">
<svg class="md-svg">
<defs>
</defs>
</svg>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
<a href="../#testing" tabindex="1" class="md-skip">
Skip to content
</a>
<header class="md-header" data-md-component="header">
<nav class="md-header-nav md-grid">
<div class="md-flex">
<div class="md-flex__cell md-flex__cell--shrink">
<a href="https://pages.charlesreid1.com/translate-yer-docs" title="translate-yer-docs" class="md-header-nav__button md-logo">
<i class="md-icon">insert_drive_file arrow_right_alt g_translate arrow_right_alt insert_drive_file</i>
</a>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--menu md-header-nav__button" for="__drawer"></label>
</div>
<div class="md-flex__cell md-flex__cell--stretch">
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title">
<span class="md-header-nav__topic">
translate-yer-docs
</span>
<span class="md-header-nav__topic">
Testing
</span>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--search md-header-nav__button" for="__search"></label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active">
<label class="md-icon md-search__icon" for="__search"></label>
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1">
&#xE5CD;
</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="result">
<div class="md-search-result__meta">
Type to start searching
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<div class="md-header-nav__source">
<a href="https://git.charlesreid1.com/charlesreid1/translate-yer-docs" title="Go to repository" class="md-source" data-md-source="">
<div class="md-source__repository">
translate-yer-docs
</div>
</a>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container">
<main class="md-main">
<div class="md-main__inner md-grid" data-md-component="container">
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" data-md-level="0">
<label class="md-nav__title md-nav__title--site" for="__drawer">
<a href="https://pages.charlesreid1.com/translate-yer-docs" title="translate-yer-docs" class="md-nav__button md-logo">
<i class="md-icon">insert_drive_file arrow_right_alt g_translate arrow_right_alt insert_drive_file</i>
</a>
translate-yer-docs
</label>
<div class="md-nav__source">
<a href="https://git.charlesreid1.com/charlesreid1/translate-yer-docs" title="Go to repository" class="md-source" data-md-source="">
<div class="md-source__repository">
translate-yer-docs
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." title="Home" class="md-nav__link">
Home
</a>
</li>
<li class="md-nav__item">
<a href="../Organization/" title="How This Repo is Organized" class="md-nav__link">
How This Repo is Organized
</a>
</li>
<li class="md-nav__item">
<a href="../Setup/" title="Setup" class="md-nav__link">
Setup
</a>
</li>
<li class="md-nav__item">
<a href="../PandocA/" title="Pandoc: Markdown to JSON" class="md-nav__link">
Pandoc: Markdown to JSON
</a>
</li>
<li class="md-nav__item">
<a href="../PandocB/" title="Pandoc: JSON to JSON" class="md-nav__link">
Pandoc: JSON to JSON
</a>
</li>
<li class="md-nav__item">
<a href="../PanfluteA/" title="Panflute: Translate" class="md-nav__link">
Panflute: Translate
</a>
</li>
<li class="md-nav__item">
<a href="../PanfluteB/" title="Panflute: Page Elements" class="md-nav__link">
Panflute: Page Elements
</a>
</li>
<li class="md-nav__item">
<a href="../PandocC/" title="Pandoc: JSON to Markdown" class="md-nav__link">
Pandoc: JSON to Markdown
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
Testing
</label>
<a href="./" title="Testing" class="md-nav__link md-nav__link--active">
Testing
</a>
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#testing" title="Testing" class="md-nav__link">
Testing
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../Links/" title="Links" class="md-nav__link">
Links
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#testing" title="Testing" class="md-nav__link">
Testing
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content">
<article class="md-content__inner md-typeset">
<h1>Testing</h1>
<h2 id="testing">Testing<a class="headerlink" href="#testing" title="Permanent link">&para;</a></h2>
<p>To test the pandoc filter to make sure it is working, you can
create some Markdown in a file or from the command line, and feed it
through pandoc and into the filter:</p>
<div class="codehilite"><pre><span></span>$ echo &quot;This is a [paragraph](https://example.com) of markdown text.&quot; | pandoc -t json -f gfm -s | ./ruskie.py
</pre></div>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href="../PandocC/" title="Pandoc: JSON to Markdown" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div>
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Previous
</span>
Pandoc: JSON to Markdown
</span>
</div>
</a>
<a href="../Links/" title="Links" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Next
</span>
Links
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i>
</div>
</a>
</nav>
</div>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
<div class="md-footer-copyright__highlight">
Copyright &copy; 2018 <a href="https://charlesreid1.com">Charles Reid</a>, released under the <a href="https://opensource.org/licenses/MIT">MIT License</a>.
</div>
powered by
<a href="https://www.mkdocs.org">MkDocs</a>
and
<a href="https://squidfunk.github.io/mkdocs-material/">
Material for MkDocs</a>
</div>
</div>
</div>
</footer>
</div>
<script src="../assets/javascripts/application.e72fd936.js"></script>
<script>app.initialize({version:"1.0",url:{base:".."}})</script>
<script src="../search/main.js"></script>
</body>
</html>

62
api_translate

@ -1,62 +0,0 @@
#!/usr/bin/env python
import os, glob, subprocess
import pypandoc
"""
Translate Pipeline Using Pandoc API
Use glob to find all markdown files in `rmm/docs/`
For each one, run the pipeline using api:
- for each document in `rmm/docs/`
- pandoc markdown-to-json
- panflute filter to translate json and extract links
- pandoc json-to-markdown
- output documents in translated_docs/
TODO:
- call the pandoc API directly to avoid subprocess
"""
SOURCE_DOCS = 'source'
TARGET_DOCS = 'target'
TRANSLATE_FILTER = 'filters/shift_links.py'
if not os.path.isdir(os.path.join(os.getcwd(),SOURCE_DOCS)):
err = "ERROR: No source docs folder found.\n"
err += "Looked in %s\n"%(os.path.join(os.getcwd(),SOURCE_DOCS))
raise Exception(err)
cwd = os.getcwd()
print("[+] Welcome to translate the docs!")
print("[+] Making directory for translated documentation: %s"%(TARGET_DOCS))
subprocess.call(['mkdir','-p',TARGET_DOCS], cwd=cwd)
markdown_files = []
for fdir,fdirnames,fnames in os.walk(os.path.join(os.getcwd(),SOURCE_DOCS)):
for f in fnames:
##########
## FIXME
#if f[-3:]=='.md':
if f=='index.md':
markdown_files.append( os.path.join( fdir, f ) )
for en_md in markdown_files:
filters = [TRANSLATE_FILTER]
output = pypandoc.convert_file(en_md,
to='gfm',
format='gfm',
filters=filters)
print(output)
print("="*40)
print("="*40)
print("[+] All done!")

4
assets/fonts/font-awesome.css vendored

File diff suppressed because one or more lines are too long

13
assets/fonts/material-icons.css

@ -0,0 +1,13 @@
/*!
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, SOFTWARE
* DISTRIBUTED UNDER THE LICENSE IS DISTRIBUTED ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
* SEE THE LICENSE FOR THE SPECIFIC LANGUAGE GOVERNING PERMISSIONS AND
* LIMITATIONS UNDER THE LICENSE.
*/@font-face{font-family:"Material Icons";font-style:normal;font-weight:400;src:local("Material Icons"),local("MaterialIcons-Regular"),url("specimen/MaterialIcons-Regular.woff2") format("woff2"),url("specimen/MaterialIcons-Regular.woff") format("woff"),url("specimen/MaterialIcons-Regular.ttf") format("truetype")}

BIN
assets/fonts/specimen/FontAwesome.ttf

Binary file not shown.

BIN
assets/fonts/specimen/FontAwesome.woff

Binary file not shown.

BIN
assets/fonts/specimen/FontAwesome.woff2

Binary file not shown.

BIN
assets/fonts/specimen/MaterialIcons-Regular.ttf

Binary file not shown.

BIN
assets/fonts/specimen/MaterialIcons-Regular.woff

Binary file not shown.

BIN
assets/fonts/specimen/MaterialIcons-Regular.woff2

Binary file not shown.

BIN
assets/images/favicon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 521 B

20
assets/images/icons/bitbucket.1b09e088.svg

@ -0,0 +1,20 @@
<svg xmlns="http://www.w3.org/2000/svg" width="352" height="448"
viewBox="0 0 352 448" id="__bitbucket">
<path fill="currentColor" d="M203.75 214.75q2 15.75-12.625 25.25t-27.875
1.5q-9.75-4.25-13.375-14.5t-0.125-20.5 13-14.5q9-4.5 18.125-3t16 8.875
6.875 16.875zM231.5 209.5q-3.5-26.75-28.25-41t-49.25-3.25q-15.75
7-25.125 22.125t-8.625 32.375q1 22.75 19.375 38.75t41.375 14q22.75-2
38-21t12.5-42zM291.25
74q-5-6.75-14-11.125t-14.5-5.5-17.75-3.125q-72.75-11.75-141.5 0.5-10.75
1.75-16.5 3t-13.75 5.5-12.5 10.75q7.5 7 19 11.375t18.375 5.5 21.875
2.875q57 7.25 112 0.25 15.75-2 22.375-3t18.125-5.375 18.75-11.625zM305.5
332.75q-2 6.5-3.875 19.125t-3.5 21-7.125 17.5-14.5 14.125q-21.5
12-47.375 17.875t-50.5 5.5-50.375-4.625q-11.5-2-20.375-4.5t-19.125-6.75-18.25-10.875-13-15.375q-6.25-24-14.25-73l1.5-4
4.5-2.25q55.75 37 126.625 37t126.875-37q5.25 1.5 6 5.75t-1.25 11.25-2
9.25zM350.75 92.5q-6.5 41.75-27.75 163.75-1.25 7.5-6.75 14t-10.875
10-13.625 7.75q-63 31.5-152.5
22-62-6.75-98.5-34.75-3.75-3-6.375-6.625t-4.25-8.75-2.25-8.5-1.5-9.875-1.375-8.75q-2.25-12.5-6.625-37.5t-7-40.375-5.875-36.875-5.5-39.5q0.75-6.5
4.375-12.125t7.875-9.375 11.25-7.5 11.5-5.625 12-4.625q31.25-11.5
78.25-16 94.75-9.25 169 12.5 38.75 11.5 53.75 30.5 4 5 4.125
12.75t-1.375 13.5z" />
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

18
assets/images/icons/github.f0b8504a.svg

@ -0,0 +1,18 @@
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448"
viewBox="0 0 416 448" id="__github">
<path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19-18.125
8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5
18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75
19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19
18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360
304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25
2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8
38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0
37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25
82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75
1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75
0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25
30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5
46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34
99.5z" />
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

38
assets/images/icons/gitlab.6dd19c00.svg

@ -0,0 +1,38 @@
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500"
viewBox="0 0 500 500" id="__gitlab">
<g transform="translate(156.197863, 1.160267)">
<path fill="currentColor"
d="M93.667,473.347L93.667,473.347l90.684-279.097H2.983L93.667,
473.347L93.667,473.347z" />
</g>
<g transform="translate(28.531199, 1.160800)" opacity="0.7">
<path fill="currentColor"
d="M221.333,473.345L130.649,194.25H3.557L221.333,473.345L221.333,
473.345z" />
</g>
<g transform="translate(0.088533, 0.255867)" opacity="0.5">
<path fill="currentColor"
d="M32,195.155L32,195.155L4.441,279.97c-2.513,7.735,0.24,16.21,6.821,
20.99l238.514,173.29 L32,195.155L32,195.155z" />
</g>
<g transform="translate(29.421866, 280.255593)">
<path fill="currentColor"
d="M2.667-84.844h127.092L75.14-252.942c-2.811-8.649-15.047-8.649-17.856,
0L2.667-84.844 L2.667-84.844z" />
</g>
<g transform="translate(247.197860, 1.160800)" opacity="0.7">
<path fill="currentColor"
d="M2.667,473.345L93.351,194.25h127.092L2.667,473.345L2.667,
473.345z" />
</g>
<g transform="translate(246.307061, 0.255867)" opacity="0.5">
<path fill="currentColor"
d="M221.334,195.155L221.334,195.155l27.559,84.815c2.514,7.735-0.24,
16.21-6.821,20.99 L3.557,474.25L221.334,195.155L221.334,195.155z" />
</g>
<g transform="translate(336.973725, 280.255593)">
<path fill="currentColor"
d="M130.667-84.844H3.575l54.618-168.098c2.811-8.649,15.047-8.649,
17.856,0L130.667-84.844 L130.667-84.844z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

1
assets/javascripts/application.e72fd936.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/lunr.da.js

@ -0,0 +1 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r,i,n;e.da=function(){this.pipeline.reset(),this.pipeline.add(e.da.trimmer,e.da.stopWordFilter,e.da.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.da.stemmer))},e.da.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.da.trimmer=e.trimmerSupport.generateTrimmer(e.da.wordCharacters),e.Pipeline.registerFunction(e.da.trimmer,"trimmer-da"),e.da.stemmer=(r=e.stemmerSupport.Among,i=e.stemmerSupport.SnowballProgram,n=new function(){var e,n,t,s=[new r("hed",-1,1),new r("ethed",0,1),new r("ered",-1,1),new r("e",-1,1),new r("erede",3,1),new r("ende",3,1),new r("erende",5,1),new r("ene",3,1),new r("erne",3,1),new r("ere",3,1),new r("en",-1,1),new r("heden",10,1),new r("eren",10,1),new r("er",-1,1),new r("heder",13,1),new r("erer",13,1),new r("s",-1,2),new r("heds",16,1),new r("es",16,1),new r("endes",18,1),new r("erendes",19,1),new r("enes",18,1),new r("ernes",18,1),new r("eres",18,1),new r("ens",16,1),new r("hedens",24,1),new r("erens",24,1),new r("ers",16,1),new r("ets",16,1),new r("erets",28,1),new r("et",-1,1),new r("eret",30,1)],o=[new r("gd",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1)],a=[new r("ig",-1,1),new r("lig",0,1),new r("elig",1,1),new r("els",-1,1),new r("løst",-1,2)],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],u=[239,254,42,3,0,0,0,0,0,0,0,0,0,0,0,0,16],c=new i;function l(){var e,r=c.limit-c.cursor;c.cursor>=n&&(e=c.limit_backward,c.limit_backward=n,c.ket=c.cursor,c.find_among_b(o,4)?(c.bra=c.cursor,c.limit_backward=e,c.cursor=c.limit-r,c.cursor>c.limit_backward&&(c.cursor--,c.bra=c.cursor,c.slice_del())):c.limit_backward=e)}this.setCurrent=function(e){c.setCurrent(e)},this.getCurrent=function(){return c.getCurrent()},this.stem=function(){var r,i=c.cursor;return function(){var r,i=c.cursor+3;if(n=c.limit,0<=i&&i<=c.limit){for(e=i;;){if(r=c.cursor,c.in_grouping(d,97,248)){c.cursor=r;break}if(c.cursor=r,r>=c.limit)return;c.cursor++}for(;!c.out_grouping(d,97,248);){if(c.cursor>=c.limit)return;c.cursor++}(n=c.cursor)<e&&(n=e)}}(),c.limit_backward=i,c.cursor=c.limit,function(){var e,r;if(c.cursor>=n&&(r=c.limit_backward,c.limit_backward=n,c.ket=c.cursor,e=c.find_among_b(s,32),c.limit_backward=r,e))switch(c.bra=c.cursor,e){case 1:c.slice_del();break;case 2:c.in_grouping_b(u,97,229)&&c.slice_del()}}(),c.cursor=c.limit,l(),c.cursor=c.limit,function(){var e,r,i,t=c.limit-c.cursor;if(c.ket=c.cursor,c.eq_s_b(2,"st")&&(c.bra=c.cursor,c.eq_s_b(2,"ig")&&c.slice_del()),c.cursor=c.limit-t,c.cursor>=n&&(r=c.limit_backward,c.limit_backward=n,c.ket=c.cursor,e=c.find_among_b(a,5),c.limit_backward=r,e))switch(c.bra=c.cursor,e){case 1:c.slice_del(),i=c.limit-c.cursor,l(),c.cursor=c.limit-i;break;case 2:c.slice_from("løs")}}(),c.cursor=c.limit,c.cursor>=n&&(r=c.limit_backward,c.limit_backward=n,c.ket=c.cursor,c.out_grouping_b(d,97,248)?(c.bra=c.cursor,t=c.slice_to(t),c.limit_backward=r,c.eq_v_b(t)&&c.slice_del()):c.limit_backward=r),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}),e.Pipeline.registerFunction(e.da.stemmer,"stemmer-da"),e.da.stopWordFilter=e.generateStopWordFilter("ad af alle alt anden at blev blive bliver da de dem den denne der deres det dette dig din disse dog du efter eller en end er et for fra ham han hans har havde have hende hendes her hos hun hvad hvis hvor i ikke ind jeg jer jo kunne man mange med meget men mig min mine mit mod ned noget nogle nu når og også om op os over på selv sig sin sine sit skal skulle som sådan thi til ud under var vi vil ville vor være været".split(" ")),e.Pipeline.registerFunction(e.da.stopWordFilter,"stopWordFilter-da")}});

1
assets/javascripts/lunr/lunr.de.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/lunr.du.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/lunr.es.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/lunr.fi.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/lunr.fr.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/lunr.hu.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/lunr.it.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/lunr.jp.js

@ -0,0 +1 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.jp=function(){this.pipeline.reset(),this.pipeline.add(e.jp.stopWordFilter,e.jp.stemmer),r?this.tokenizer=e.jp.tokenizer:(e.tokenizer&&(e.tokenizer=e.jp.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.jp.tokenizer))};var t=new e.TinySegmenter;e.jp.tokenizer=function(n){if(!arguments.length||null==n||null==n)return[];if(Array.isArray(n))return n.map(function(t){return r?new e.Token(t.toLowerCase()):t.toLowerCase()});for(var i=n.toString().toLowerCase().replace(/^\s+/,""),o=i.length-1;o>=0;o--)if(/\S/.test(i.charAt(o))){i=i.substring(0,o+1);break}return t.segment(i).filter(function(e){return!!e}).map(function(t){return r?new e.Token(t):t})},e.jp.stemmer=function(e){return e},e.Pipeline.registerFunction(e.jp.stemmer,"stemmer-jp"),e.jp.wordCharacters="一二三四五六七八九十百千万億兆一-龠々〆ヵヶぁ-んァ-ヴーア-ン゙a-zA-Za-zA-Z0-90-9",e.jp.stopWordFilter=function(t){if(-1===e.jp.stopWordFilter.stopWords.indexOf(r?t.toString():t))return t},e.jp.stopWordFilter=e.generateStopWordFilter("これ それ あれ この その あの ここ そこ あそこ こちら どこ だれ なに なん 何 私 貴方 貴方方 我々 私達 あの人 あのかた 彼女 彼 です あります おります います は が の に を で え から まで より も どの と し それで しかし".split(" ")),e.Pipeline.registerFunction(e.jp.stopWordFilter,"stopWordFilter-jp")}});

1
assets/javascripts/lunr/lunr.multi.js

@ -0,0 +1 @@
!function(e,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(e.lunr)}(this,function(){return function(e){e.multiLanguage=function(){for(var i=Array.prototype.slice.call(arguments),t=i.join("-"),r="",n=[],s=[],p=0;p<i.length;++p)"en"==i[p]?(r+="\\w",n.unshift(e.stopWordFilter),n.push(e.stemmer),s.push(e.stemmer)):(r+=e[i[p]].wordCharacters,n.unshift(e[i[p]].stopWordFilter),n.push(e[i[p]].stemmer),s.push(e[i[p]].stemmer));var o=e.trimmerSupport.generateTrimmer(r);return e.Pipeline.registerFunction(o,"lunr-multi-trimmer-"+t),n.unshift(o),function(){this.pipeline.reset(),this.pipeline.add.apply(this.pipeline,n),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add.apply(this.searchPipeline,s))}}}});

1
assets/javascripts/lunr/lunr.no.js

@ -0,0 +1 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r,n,i;e.no=function(){this.pipeline.reset(),this.pipeline.add(e.no.trimmer,e.no.stopWordFilter,e.no.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.no.stemmer))},e.no.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.no.trimmer=e.trimmerSupport.generateTrimmer(e.no.wordCharacters),e.Pipeline.registerFunction(e.no.trimmer,"trimmer-no"),e.no.stemmer=(r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){var e,i,t=[new r("a",-1,1),new r("e",-1,1),new r("ede",1,1),new r("ande",1,1),new r("ende",1,1),new r("ane",1,1),new r("ene",1,1),new r("hetene",6,1),new r("erte",1,3),new r("en",-1,1),new r("heten",9,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",12,1),new r("s",-1,2),new r("as",14,1),new r("es",14,1),new r("edes",16,1),new r("endes",16,1),new r("enes",16,1),new r("hetenes",19,1),new r("ens",14,1),new r("hetens",21,1),new r("ers",14,1),new r("ets",14,1),new r("et",-1,1),new r("het",25,1),new r("ert",-1,3),new r("ast",-1,1)],o=[new r("dt",-1,-1),new r("vt",-1,-1)],s=[new r("leg",-1,1),new r("eleg",0,1),new r("ig",-1,1),new r("eig",2,1),new r("lig",2,1),new r("elig",4,1),new r("els",-1,1),new r("lov",-1,1),new r("elov",7,1),new r("slov",7,1),new r("hetslov",9,1)],a=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],m=[119,125,149,1],l=new n;this.setCurrent=function(e){l.setCurrent(e)},this.getCurrent=function(){return l.getCurrent()},this.stem=function(){var r,n,u,d,c=l.cursor;return function(){var r,n=l.cursor+3;if(i=l.limit,0<=n||n<=l.limit){for(e=n;;){if(r=l.cursor,l.in_grouping(a,97,248)){l.cursor=r;break}if(r>=l.limit)return;l.cursor=r+1}for(;!l.out_grouping(a,97,248);){if(l.cursor>=l.limit)return;l.cursor++}(i=l.cursor)<e&&(i=e)}}(),l.limit_backward=c,l.cursor=l.limit,function(){var e,r,n;if(l.cursor>=i&&(r=l.limit_backward,l.limit_backward=i,l.ket=l.cursor,e=l.find_among_b(t,29),l.limit_backward=r,e))switch(l.bra=l.cursor,e){case 1:l.slice_del();break;case 2:n=l.limit-l.cursor,l.in_grouping_b(m,98,122)?l.slice_del():(l.cursor=l.limit-n,l.eq_s_b(1,"k")&&l.out_grouping_b(a,97,248)&&l.slice_del());break;case 3:l.slice_from("er")}}(),l.cursor=l.limit,n=l.limit-l.cursor,l.cursor>=i&&(r=l.limit_backward,l.limit_backward=i,l.ket=l.cursor,l.find_among_b(o,2)?(l.bra=l.cursor,l.limit_backward=r,l.cursor=l.limit-n,l.cursor>l.limit_backward&&(l.cursor--,l.bra=l.cursor,l.slice_del())):l.limit_backward=r),l.cursor=l.limit,l.cursor>=i&&(d=l.limit_backward,l.limit_backward=i,l.ket=l.cursor,(u=l.find_among_b(s,11))?(l.bra=l.cursor,l.limit_backward=d,1==u&&l.slice_del()):l.limit_backward=d),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}),e.Pipeline.registerFunction(e.no.stemmer,"stemmer-no"),e.no.stopWordFilter=e.generateStopWordFilter("alle at av bare begge ble blei bli blir blitt både båe da de deg dei deim deira deires dem den denne der dere deres det dette di din disse ditt du dykk dykkar då eg ein eit eitt eller elles en enn er et ett etter for fordi fra før ha hadde han hans har hennar henne hennes her hjå ho hoe honom hoss hossen hun hva hvem hver hvilke hvilken hvis hvor hvordan hvorfor i ikke ikkje ikkje ingen ingi inkje inn inni ja jeg kan kom korleis korso kun kunne kva kvar kvarhelst kven kvi kvifor man mange me med medan meg meget mellom men mi min mine mitt mot mykje ned no noe noen noka noko nokon nokor nokre nå når og også om opp oss over på samme seg selv si si sia sidan siden sin sine sitt sjøl skal skulle slik so som som somme somt så sånn til um upp ut uten var vart varte ved vere verte vi vil ville vore vors vort vår være være vært å".split(" ")),e.Pipeline.registerFunction(e.no.stopWordFilter,"stopWordFilter-no")}});

1
assets/javascripts/lunr/lunr.pt.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/lunr.ro.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/lunr.ru.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/lunr.stemmer.support.js

@ -0,0 +1 @@
!function(r,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(r.lunr)}(this,function(){return function(r){r.stemmerSupport={Among:function(r,t,i,s){if(this.toCharArray=function(r){for(var t=r.length,i=new Array(t),s=0;s<t;s++)i[s]=r.charCodeAt(s);return i},!r&&""!=r||!t&&0!=t||!i)throw"Bad Among initialisation: s:"+r+", substring_i: "+t+", result: "+i;this.s_size=r.length,this.s=this.toCharArray(r),this.substring_i=t,this.result=i,this.method=s},SnowballProgram:function(){var r;return{bra:0,ket:0,limit:0,cursor:0,limit_backward:0,setCurrent:function(t){r=t,this.cursor=0,this.limit=t.length,this.limit_backward=0,this.bra=this.cursor,this.ket=this.limit},getCurrent:function(){var t=r;return r=null,t},in_grouping:function(t,i,s){if(this.cursor<this.limit){var e=r.charCodeAt(this.cursor);if(e<=s&&e>=i&&t[(e-=i)>>3]&1<<(7&e))return this.cursor++,!0}return!1},in_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e<=s&&e>=i&&t[(e-=i)>>3]&1<<(7&e))return this.cursor--,!0}return!1},out_grouping:function(t,i,s){if(this.cursor<this.limit){var e=r.charCodeAt(this.cursor);if(e>s||e<i)return this.cursor++,!0;if(!(t[(e-=i)>>3]&1<<(7&e)))return this.cursor++,!0}return!1},out_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e>s||e<i)return this.cursor--,!0;if(!(t[(e-=i)>>3]&1<<(7&e)))return this.cursor--,!0}return!1},eq_s:function(t,i){if(this.limit-this.cursor<t)return!1;for(var s=0;s<t;s++)if(r.charCodeAt(this.cursor+s)!=i.charCodeAt(s))return!1;return this.cursor+=t,!0},eq_s_b:function(t,i){if(this.cursor-this.limit_backward<t)return!1;for(var s=0;s<t;s++)if(r.charCodeAt(this.cursor-t+s)!=i.charCodeAt(s))return!1;return this.cursor-=t,!0},find_among:function(t,i){for(var s=0,e=i,n=this.cursor,u=this.limit,o=0,h=0,c=!1;;){for(var a=s+(e-s>>1),f=0,l=o<h?o:h,_=t[a],m=l;m<_.s_size;m++){if(n+l==u){f=-1;break}if(f=r.charCodeAt(n+l)-_.s[m])break;l++}if(f<0?(e=a,h=l):(s=a,o=l),e-s<=1){if(s>0||e==s||c)break;c=!0}}for(;;){if(o>=(_=t[s]).s_size){if(this.cursor=n+_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n+_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},find_among_b:function(t,i){for(var s=0,e=i,n=this.cursor,u=this.limit_backward,o=0,h=0,c=!1;;){for(var a=s+(e-s>>1),f=0,l=o<h?o:h,_=(m=t[a]).s_size-1-l;_>=0;_--){if(n-l==u){f=-1;break}if(f=r.charCodeAt(n-1-l)-m.s[_])break;l++}if(f<0?(e=a,h=l):(s=a,o=l),e-s<=1){if(s>0||e==s||c)break;c=!0}}for(;;){var m;if(o>=(m=t[s]).s_size){if(this.cursor=n-m.s_size,!m.method)return m.result;var b=m.method();if(this.cursor=n-m.s_size,b)return m.result}if((s=m.substring_i)<0)return 0}},replace_s:function(t,i,s){var e=s.length-(i-t),n=r.substring(0,t),u=r.substring(i);return r=n+s+u,this.limit+=e,this.cursor>=i?this.cursor+=e:this.cursor>t&&(this.cursor=t),e},slice_check:function(){if(this.bra<0||this.bra>this.ket||this.ket>this.limit||this.limit>r.length)throw"faulty slice operation"},slice_from:function(r){this.slice_check(),this.replace_s(this.bra,this.ket,r)},slice_del:function(){this.slice_from("")},insert:function(r,t,i){var s=this.replace_s(r,t,i);r<=this.bra&&(this.bra+=s),r<=this.ket&&(this.ket+=s)},slice_to:function(){return this.slice_check(),r.substring(this.bra,this.ket)},eq_v_b:function(r){return this.eq_s_b(r.length,r)}}}},r.trimmerSupport={generateTrimmer:function(r){var t=new RegExp("^[^"+r+"]+"),i=new RegExp("[^"+r+"]+$");return function(r){return"function"==typeof r.update?r.update(function(r){return r.replace(t,"").replace(i,"")}):r.replace(t,"").replace(i,"")}}}}});

1
assets/javascripts/lunr/lunr.sv.js

@ -0,0 +1 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r,n,t;e.sv=function(){this.pipeline.reset(),this.pipeline.add(e.sv.trimmer,e.sv.stopWordFilter,e.sv.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.sv.stemmer))},e.sv.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.sv.trimmer=e.trimmerSupport.generateTrimmer(e.sv.wordCharacters),e.Pipeline.registerFunction(e.sv.trimmer,"trimmer-sv"),e.sv.stemmer=(r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,t=new function(){var e,t,i=[new r("a",-1,1),new r("arna",0,1),new r("erna",0,1),new r("heterna",2,1),new r("orna",0,1),new r("ad",-1,1),new r("e",-1,1),new r("ade",6,1),new r("ande",6,1),new r("arne",6,1),new r("are",6,1),new r("aste",6,1),new r("en",-1,1),new r("anden",12,1),new r("aren",12,1),new r("heten",12,1),new r("ern",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",18,1),new r("or",-1,1),new r("s",-1,2),new r("as",21,1),new r("arnas",22,1),new r("ernas",22,1),new r("ornas",22,1),new r("es",21,1),new r("ades",26,1),new r("andes",26,1),new r("ens",21,1),new r("arens",29,1),new r("hetens",29,1),new r("erns",21,1),new r("at",-1,1),new r("andet",-1,1),new r("het",-1,1),new r("ast",-1,1)],s=[new r("dd",-1,-1),new r("gd",-1,-1),new r("nn",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1),new r("tt",-1,-1)],a=[new r("ig",-1,1),new r("lig",0,1),new r("els",-1,1),new r("fullt",-1,3),new r("löst",-1,2)],o=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,24,0,32],u=[119,127,149],m=new n;this.setCurrent=function(e){m.setCurrent(e)},this.getCurrent=function(){return m.getCurrent()},this.stem=function(){var r,n=m.cursor;return function(){var r,n=m.cursor+3;if(t=m.limit,0<=n||n<=m.limit){for(e=n;;){if(r=m.cursor,m.in_grouping(o,97,246)){m.cursor=r;break}if(m.cursor=r,m.cursor>=m.limit)return;m.cursor++}for(;!m.out_grouping(o,97,246);){if(m.cursor>=m.limit)return;m.cursor++}(t=m.cursor)<e&&(t=e)}}(),m.limit_backward=n,m.cursor=m.limit,function(){var e,r=m.limit_backward;if(m.cursor>=t&&(m.limit_backward=t,m.cursor=m.limit,m.ket=m.cursor,e=m.find_among_b(i,37),m.limit_backward=r,e))switch(m.bra=m.cursor,e){case 1:m.slice_del();break;case 2:m.in_grouping_b(u,98,121)&&m.slice_del()}}(),m.cursor=m.limit,r=m.limit_backward,m.cursor>=t&&(m.limit_backward=t,m.cursor=m.limit,m.find_among_b(s,7)&&(m.cursor=m.limit,m.ket=m.cursor,m.cursor>m.limit_backward&&(m.bra=--m.cursor,m.slice_del())),m.limit_backward=r),m.cursor=m.limit,function(){var e,r;if(m.cursor>=t){if(r=m.limit_backward,m.limit_backward=t,m.cursor=m.limit,m.ket=m.cursor,e=m.find_among_b(a,5))switch(m.bra=m.cursor,e){case 1:m.slice_del();break;case 2:m.slice_from("lös");break;case 3:m.slice_from("full")}m.limit_backward=r}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return t.setCurrent(e),t.stem(),t.getCurrent()}):(t.setCurrent(e),t.stem(),t.getCurrent())}),e.Pipeline.registerFunction(e.sv.stemmer,"stemmer-sv"),e.sv.stopWordFilter=e.generateStopWordFilter("alla allt att av blev bli blir blivit de dem den denna deras dess dessa det detta dig din dina ditt du där då efter ej eller en er era ert ett från för ha hade han hans har henne hennes hon honom hur här i icke ingen inom inte jag ju kan kunde man med mellan men mig min mina mitt mot mycket ni nu när någon något några och om oss på samma sedan sig sin sina sitta själv skulle som så sådan sådana sådant till under upp ut utan vad var vara varför varit varje vars vart vem vi vid vilka vilkas vilken vilket vår våra vårt än är åt över".split(" ")),e.Pipeline.registerFunction(e.sv.stopWordFilter,"stopWordFilter-sv")}});

1
assets/javascripts/lunr/lunr.tr.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/tinyseg.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/modernizr.1aa3b519.js

File diff suppressed because one or more lines are too long

1176
assets/stylesheets/application-palette.22915126.css

File diff suppressed because it is too large Load Diff

2552
assets/stylesheets/application.451f80e5.css

File diff suppressed because it is too large Load Diff

23
docs/Links.md

@ -1,23 +0,0 @@
## Useful Links
* Markdown to structured JSON using pandoc:
* [Text.Pandoc.JSON](https://hackage.haskell.org/package/pandoc-types-1.17.4.2/docs/Text-Pandoc-JSON.html)
* How to write Pandoc filters using Python:
* [pandocfilters](https://pypi.org/project/pandocfilters/)
* Example reading from stdin:
* `pandoc -t json -s | ./caps.py | pandoc -f json`
* Link to examples:
* [pandocfilters examples](https://github.com/jgm/pandocfilters/tree/master/examples)
* [caps.py](https://github.com/jgm/pandocfilters/blob/master/examples/caps.py)
* requests library Python:
* [requests quickstart](http://docs.python-requests.org/en/latest/user/quickstart/)
* `>>> r = requests.put('http://httpbin.org/put', data = {'key':'value'})`
* pandocfilters
* [pandocfilters](https://github.com/jgm/pandocfilters)
* also see [but i don't want to learn haskell](http://pandoc.org/filters.html#but-i-dont-want-to-learn-haskell) on pandoc.org.

87
docs/Organization.md

@ -1,87 +0,0 @@
Here is a rundown of the directory structure
of translate the docs:
## Documentation
All of the documentation for how to translate the docs
lives in markdown files in `docs/`.
This is converted to HTML documentation using `mkdocs`.
The configuration for mkdocs is in `mkdocs.yml`.
The mkdocs theme used is mkdocs-material, which is in the
git submodule `mkdocs-material/`.
The static content is on the `gh-pages` branch and is hosted
on `https://pages.charlesreid1.com/` and on Github Pages.
## Translation
The document is first parsed with pandoc to convert markdown
to JSON.
The JSON is passed to a panflute filter, which processes the text.
Translation magic happens using the Google Cloud Translate API,
which is called by the panflute filter.
Pandoc is used to convert the JSON back to (translated) markdown.
# Plans
The tool in this repository (the pandoc filter) will eventually
become a command line tool that can be run in-place from any
repository, and the translated markdown deposited into a new
directory.
This requires one major design change: rather than using pandoc
and applying filters from the command line, we must call the
pandoc API from Python directly. Then we can define the filter
as part of the command line tool, and when we call the translate
the docs tool, it applies the filter in-place.
The end result, for the user, is the ability to run a single command
that will translate their docs:
```
$ translate_the_docs --list-languages
ru
de
es
fr
ar
...
$ translate_the_docs
Before we can translate your docs, we will start with a few questions.
What directory contains your current markdown docs?
Leave empty for default: docs
Answer: docs
What language do you want to translate your markdown docs into?
Type ? for a list of languages.
Answer: ?
Possible languages: ru, de, es, fr, ar, ...
What language do you want to translate your markdown docs into?
Type ? for a list of languages.
Answer: ru
What directory do you want to contain your translated markdown docs?
Leave empty for default: ru_docs
Answer:
Translating...
Done!
```
Or set with command line options:
```
$ translate_the_docs --source=doc/ --target=ru_docs --language=ru
```

34
docs/PandocA.md

@ -1,34 +0,0 @@
This page covers the pandoc Markdown to JSON step.
### Using the Pandoc API (New Way)
(In progress)
### From the Command Line (Old Way)
We use pandoc to convert structured Markdown into JSON.
This is done using the `-f` flag to specify the input format
and the `-t` flag to specify the target format:
```text
pandoc -t json -f gfm my_markdown_file.md
```
Here, we use `gfm` (Github-flavored markdown).
We can also read documents from stdin using the `-s` flag:
```text
cat my_markdown_file.md | pandoc -t json -f gfm -s
```
The resulting JSON is ready to be parsed using a pandoc filter.
Note that if you wish to visualize the structure of the JSON
before processing it further, you can pipe it to `python -m json.tool`,
which nicely formats the JSON for printing and visualizing:
```text
cat my_markdown_file.md | pandoc -t json -f gfm -s | python -m json.tool
```

31
docs/PandocB.md

@ -1,31 +0,0 @@
This page covers the pandoc JSON to JSON step.
To translate Markdown from English to Russian,
we use pandoc to parse the Markdown file and
extract the text that needs to be translated.
Specifically, we write a JSON-to-JSON pandoc filter
using [panflute](http://scorreia.com/software/panflute/index.html),
a Python library for writing pandoc filters.
### Filtering with the Pandoc API (New Way)
(In progress)
### Filtering from the Command Line (Old Way)
The syntax is as follows:
```text
cat my_markdown_file.md | pandoc -t json -f gfm -s | filters/my_filter.py
```
The convention for panflute filters is that the JSON document
is passed into the panflute filter one component at a time.
If the filter does not return anything, the document element
will be used as-is in the final document. If a new document
element is returned, it is used in place of the old
document element.

12
docs/PandocC.md

@ -1,12 +0,0 @@
## Pandoc Parser: JSON-to-Markdown Parser
To return everything back into Markdown, the last step of the pipeline
is to add another call to pandoc, but with the formats reversed, so that
it will turn JSON back into Markdown:
```text
cat shepherd.md | pandoc -t json -f gfm -s | ./panflute_rooskie.py | pandoc -f json -t gfm -s > shepherd_ru.md
```

120
docs/PanfluteA.md

@ -1,120 +0,0 @@
To translate Markdown text to Russian, we want to look for
Para (paragraph) components, and extract the text from
each paragraph as a string.
```text
cat shepherd.md | pandoc -t json -f gfm -s | filters/translate.py
```
The `translate.py` panflute filter determines what text to translate
and calls the Google Cloud Translate API to do the translating.
We use the Google Cloud Translate API using a Python client library
that they provide, rather than fussing with assembling our own
payloads and using the `requests` library.
**`filters/translate.py`:**
```python
from panflute import *
from google.cloud import translate
def translate_document(elem, doc):
...
def main(doc=None):
return run_filter(translate_document, doc=doc)
if __name__ == "__main__":
main()
```
When we run this, it passes each document element through
`translate_document()`.
Two things we wnat to do up front:
* Extract links (these are problematic for translation,
we deal with them by removing the link from the inline text
and including a list at the bottom of the document of
the (translated) original link text, plus the link itself.
* Search for paragraphs of text, or headings, and replace text
with a translation.
To do the first, we define a function called `strip_links()`,
which will strip out all the links and add them to the bottom
of the document (more on this in a minute).
We pass this function to `elem.walk()` to apply it to every
element underneath the current element. This means we can
write the `strip_links()` function in a similar way to the
`translate_document()` function: look for specific types of
elements, and modify them accordingly.
```python
def translate_document(elem, doc):
# Walk it and look for links first
elem.walk(strip_links)
...
```
Another thing we want to do is translate paragraph text from
Russian to English. We use stringify to turn a list of Str
and Space objects into a regular string:
```python
def translate_document(elem, doc):
# Walk it and look for links first
elem.walk(strip_links)
if type(elem)==Para:
english = stringify(doc)
translation = english_to_X(english)
...
```
The `english_to_X()` function (more on this shortly) will use
the Google Cloud Translate API to translate English to our language of choice.
This requires an API key with Google Cloud (see [Setup](Setup.md)).
The translate function will return unicode text. This must be turned back into
structured text that pandoc understands, so we have to wrap words in Str()
and replace spaces with Space objects.
To do this easily with a string in panflute, use `convert_text()`:
```
english = stringify(elem)
rooskie = english_to_russian(english)
new_elems = convert_text(rooskie,input_format='markdown')
return new_elems
```
To get Google Cloud Translate API working properly,
you must export an environment variable `$GOOGLE_APPLICATION_CREDENTIALS`
that points to a JSON file with your API keys
EACH TIME YOU RUN THE SCRIPT!!!
```
############################################
############################################
############## ##############
############## NOTE ##############
############## ##############
##
## This step is required for the translate
## API calls to work. Don't leave this out.
##
############################################
############################################
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/project-key-00000.json
```

66
docs/PanfluteB.md

@ -1,66 +0,0 @@
One of the pain points of translating a document is figuring out
what to do with page elements.
## Links
## Lists
## Images
## Headers
## Links
Take hyperlinks as an example. Here's how we deal with it:
We have a `prepare()` method in our panflute filter that is run
before the document filter is applied, and a `finalize()` method
that is run after the document filter is applied.
The prepare method initializes an empty list to hold links.
As we parse each section of the document, we look for
links, and when we find a link, we add the link to a list.
When the text is translated, links are stripped out and
the original link text becomes plain text again.
Rather than try and determine which words in the
translation map to the original link text,
we simply aggregate the links at the bottom of the
document. Each link includes a translation of the
original link text that is a link to the original link.
## Panflute Filter
Let's cover a bit more of the panflute magic that makes
all of that happen.
This relies on two additional methods for the filter:
`prepare()` and `finalize()`.
The prepare method just creates an empty list that will
be used to store all of the link elements in the document:
```
def prepare(doc):
doc.linklist = []
```
We call the `elem.walk()` method on each element of the
document, so we have a chance to see each element and
determine if it is a link. If it is, we keep it simple
and just save the entire element:
```
def strip_links(elem,doc):
"""
Each link will be stripped in the translation process.
Save them for the end.
"""
if isinstance(elem,Link):
doc.linklist.append(elem)
```

90
docs/Setup.md

@ -1,90 +0,0 @@
# Setup
Rundown of necessary setup steps:
* Create Google Cloud account
* Enable Googe Cloud Translate API
* Set up gcloud command line tool
* Test gcloud command line tool
## Create Google Cloud Account
Creating a Google Cloud account requires a credit card.
Obtaining a credit card is generally straightforward,
and simply involves burrowing your way into the corporate
bureaucracy by getting a job in an IT department.
Academic institutions provide an optimal environment
for obtaining a credit card to carry out sanctioned
bot flock activities.
## Enable API
Enable the Google Cloud Translate API [here](https://cloud.google.com/translate/docs/quickstart).
## Set Up Command Line Tool
The Google Cloud SDK provides a command line tool
that has utilities for interacting with the APIs.
The prior step will give you a JSON key file.
Associate this with the command line tool using
the `auth activate-service-account` verb:
```text
gcloud auth activate-service-account --key-file=[PATH]
```
Set this permanently by setting the location of the key file
using an environment variable:
```
export GOOGLE_APPLICATION_CREDENTIALS=${PWD}/krash.json
```
## Test Command Line Tool
The API endpoint we will use is:
```text
https://translation.googleapis.com/language/translate/v2
```
To call this endpoint, we have to include
a payload containing our API key, which we
obtained earlier when we enabled the API.
The `gcloud` tool provides a way to insert
credentials easily:
The command
```text
curl -s -X POST -H "Content-Type: application/json" \
-H "Authorization: Bearer "$(gcloud auth print-access-token) \
--data "{
'q':'Rainbow mind machine is extendable to keep bots from becoming boring. There are only two components to extend. These two components have a simple and clear order of function calls. Rainbow mind machine uses sensible defaults.',
'source': 'en',
'target': 'ru',
'format': 'text'
}" "https://translation.googleapis.com/language/translate/v2"
```
should yield the result:
```text
{
"data": {
"translations": [
{
"translatedText": "Радужная машина разума расширяема, чтобы боты не становились скучными. Расширяются только два компонента. Эти два компонента имеют простой и понятный порядок вызовов функций. Машина Rainbow mind использует разумные значения по умолчанию."
}
]
}
}
```
So far, so good.

14
docs/Testing.md

@ -1,14 +0,0 @@
## Testing
To test the pandoc filter to make sure it is working, you can
create some Markdown in a file or from the command line, and feed it
through pandoc and into the filter:
```
$ echo "This is a [paragraph](https://example.com) of markdown text." | pandoc -t json -f gfm -s | ./ruskie.py
```

71
docs/index.md

@ -1,71 +0,0 @@
# translate yer docs
This repository translates yer docs into another language.
This uses the Google Cloud Translate API,
pandoc, and the panflute library to create
a translation filter for Markdown files.
See an example here: [russian-rainbow-mind-machine](https://pages.charlesreid1.com/russian-rainbow-mind-machine)
(page contains documentation for the [rainbow-mind-machine](https://pages.charlesreid1.com/b-rainbow-mind-machine)
library translated into Russian).
## How This Repo is Organized
[How this repo is organized](Organization.md)
## Part 1: Google Cloud Translate API Setup
The Google Cloud Translate API is what makes this all possible.
It is easier to translate documentation into Russian
than it is to figure out how to parse Markdown programmatically
with panflute and pandocs.
[Part 1: Setup](Setup.md)
## Part 2: Pandoc
We want to parse and translate Markdown written
in English, and turn it into Markdown written in
Russian. We use pandoc to parse the Markdown file
and identify the bits that can be translated,
pass them to the Google Cloud Translate API,
and convert the translated text back into
Markdown.
Part 2: Pandoc:
[Pandoc: Markdown to JSON](PandocA.md)
[Pandoc: JSON to JSON](PandocB.md)
## Part 3: Panflute
Panflute is a Python library for writing Pandoc filters.
It is picky and tricky.
Part 3: Panflute:
[Panflute: Translate](PanfluteA.md)
[Panflute: Page Elements](PanfluteB.md)
## Part 4: Pandoc
The panflute filter will process JSON and return more JSON,
so we have one last step, which is converting the final
JSON document into Markdown.
[Part 4: Pandoc: JSON to Markdown](PandocC.md)
## Part 5: Testing
You do want to write tests for all of this stuff, don't you?
[Part 5: Testing](Testing.md)
## Part 6: Useful Links
[Part 6: Useful Links](Links.md)

86
filters/ruskie.py

@ -1,86 +0,0 @@
#!/usr/bin/env python
from panflute import *
import sys
from google.cloud import translate
from google.api_core.exceptions import Forbidden
def english_to_russian(english):
"""
Use Google Cloud Translate API to translate English to Russian
"""
try:
translate_client = translate.Client()
ru = translate_client.translate(
english,
target_language='ru')
ru = ru['translatedText']
return ru
except Forbidden as e:
sys.stderr.write(str(e))
sys.stderr.write("Error calling Google Cloud Translate API\n")
sys.stderr.write("Continuing...\n")
pass
def prepare(doc):
doc.linklist = []
def translate_document(elem, doc):
"""
Extract text from select elements and translate them
"""
if type(elem)==Para:
# Walk it and look for links first
elem.walk(strip_links)
english = stringify(elem)
rooskie = english_to_russian(english)
new_elems = convert_text(rooskie,input_format='markdown')
return new_elems
elif type(elem)==Header:
english = stringify(elem)
rooskie = english_to_russian(english)
h = Header(Str(rooskie))
return h
def strip_links(elem,doc):
"""
Each link will be stripped in the translation process.
Save them for the end.
"""
if isinstance(elem,Link):
doc.linklist.append(elem)
def finalize(doc):
"""
Create an unordered list at the end of the document
containing all of the links.
"""
en = "Links"
ru = english_to_russian(en)
h = Header(Str(ru), level=1)
doc.content.insert(len(doc.content),h)
for link in doc.linklist:
en = stringify(link)
ru = english_to_russian(en)
link2 = Link(Str(ru), url=link.url)
doc.content.insert(len(doc.content),Para(link2))
def main(doc=None):
return run_filter(translate_document, prepare, finalize, doc=doc)
if __name__=="__main__":
main()

0
filters/shift_images.py

68
filters/shift_links.py

@ -1,68 +0,0 @@
#!/usr/bin/env python
from panflute import *
import sys
def translate(english):
"""
Super advanced machine learning.
Guaranteed accurate tanslation.
"""
return english
def strip_links(elem,doc):
"""
Each link will be stripped in the translation process.
Save them for the end.
"""
if isinstance(elem,Link):
doc.linklist.append(Para(elem))
##############################
# Pandoc functions
def prepare(doc):
doc.linklist = []
def translate_document(elem, doc):
"""
Fake-translate a document
"""
if type(elem)==Para:
# Walk it and look for links first
doc.linklist = []
elem.walk(strip_links)
english = stringify(elem)
translation = translate(english)
new_elems = convert_text(translation, input_format='markdown')
return new_elems + doc.linklist
elif type(elem)==Header:
english = stringify(elem)
translation = translate(english)
h = Header(Str(translation))
return h
def finalize(doc):
pass
#########################
# Apply pandoc functions
def main(doc=None):
return run_filter(translate_document, prepare, finalize, doc=doc)
if __name__=="__main__":
main()

34
filters/strip_everything.py

@ -1,34 +0,0 @@
#!/usr/bin/env python
from panflute import *
import sys
def translate(english):
"""
Super advanced machine learning.
Guaranteed accurate tanslation.
"""
return english
def translate_document(elem, doc):
"""
Fake-translate a document
"""
if type(elem)==Para:
english = stringify(elem)
translation = translate(english)
new_elems = convert_text(translation, input_format='markdown')
return new_elems
elif type(elem)==Header:
english = stringify(elem)
translation = translate(english)
h = Header(Str(translation))
return h
def main(doc=None):
return run_filter(translate_document, doc=doc)
if __name__=="__main__":
main()

86
filters/translate.py

@ -1,86 +0,0 @@
#!/usr/bin/env python
from panflute import *
import sys
from google.cloud import translate
from google.api_core.exceptions import Forbidden
def english_to_russian(english):
"""
Use Google Cloud Translate API to translate English to Russian
"""
try:
translate_client = translate.Client()
ru = translate_client.translate(
english,
target_language='ru')
ru = ru['translatedText']
return ru
except Forbidden as e:
sys.stderr.write(str(e))
sys.stderr.write("Error calling Google Cloud Translate API\n")
sys.stderr.write("Continuing...\n")
pass
def prepare(doc):
doc.linklist = []
def translate_document(elem, doc):
"""
Extract text from select elements and translate them
"""
if type(elem)==Para:
# Walk it and look for links first
elem.walk(strip_links)
english = stringify(elem)
rooskie = english_to_russian(english)
new_elems = convert_text(rooskie,input_format='markdown')
return new_elems
elif type(elem)==Header:
english = stringify(elem)
rooskie = english_to_russian(english)
h = Header(Str(rooskie))
return h
def strip_links(elem,doc):
"""
Each link will be stripped in the translation process.
Save them for the end.
"""
if isinstance(elem,Link):
doc.linklist.append(elem)
def finalize(doc):
"""
Create an unordered list at the end of the document
containing all of the links.
"""
en = "Links"
ru = english_to_russian(en)
h = Header(Str(ru), level=1)
doc.content.insert(len(doc.content),h)
for link in doc.linklist:
en = stringify(link)
ru = english_to_russian(en)
link2 = Link(Str(ru), url=link.url)
doc.content.insert(len(doc.content),Para(link2))
def main(doc=None):
return run_filter(translate_document, prepare, finalize, doc=doc)
if __name__=="__main__":
main()

611
index.html

@ -0,0 +1,611 @@
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link rel="canonical" href="https://pages.charlesreid1.com/translate-yer-docs/">
<meta name="lang:clipboard.copy" content="Copy to clipboard">
<meta name="lang:clipboard.copied" content="Copied to clipboard">
<meta name="lang:search.language" content="en">
<meta name="lang:search.pipeline.stopwords" content="True">
<meta name="lang:search.pipeline.trimmer" content="True">
<meta name="lang:search.result.none" content="No matching documents">
<meta name="lang:search.result.one" content="1 matching document">
<meta name="lang:search.result.other" content="# matching documents">
<meta name="lang:search.tokenizer" content="[\s\-]+">
<link rel="shortcut icon" href=".">
<meta name="generator" content="mkdocs-1.0, mkdocs-material-3.0.3">
<title>translate-yer-docs</title>
<link rel="stylesheet" href="assets/stylesheets/application.451f80e5.css">
<link rel="stylesheet" href="assets/stylesheets/application-palette.22915126.css">
<meta name="theme-color" content="#3f51b5">
<script src="assets/javascripts/modernizr.1aa3b519.js"></script>
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Ubuntu:300,400,400i,700|Ubuntu+Mono">
<style>body,input{font-family:"Ubuntu","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Ubuntu Mono","Courier New",Courier,monospace}</style>
<link rel="stylesheet" href="assets/fonts/material-icons.css">
<link rel="stylesheet" href="css/custom.css">
</head>
<body dir="ltr" data-md-color-primary="indigo" data-md-color-accent="indigo">
<svg class="md-svg">
<defs>
</defs>
</svg>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
<a href="#translate-yer-docs" tabindex="1" class="md-skip">
Skip to content
</a>
<header class="md-header" data-md-component="header">
<nav class="md-header-nav md-grid">
<div class="md-flex">
<div class="md-flex__cell md-flex__cell--shrink">
<a href="https://pages.charlesreid1.com/translate-yer-docs" title="translate-yer-docs" class="md-header-nav__button md-logo">
<i class="md-icon">insert_drive_file arrow_right_alt g_translate arrow_right_alt insert_drive_file</i>
</a>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--menu md-header-nav__button" for="__drawer"></label>
</div>
<div class="md-flex__cell md-flex__cell--stretch">
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title">
<span class="md-header-nav__topic">
translate-yer-docs
</span>
<span class="md-header-nav__topic">
Home
</span>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--search md-header-nav__button" for="__search"></label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active">
<label class="md-icon md-search__icon" for="__search"></label>
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1">
&#xE5CD;
</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="result">
<div class="md-search-result__meta">
Type to start searching
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<div class="md-header-nav__source">
<a href="https://git.charlesreid1.com/charlesreid1/translate-yer-docs" title="Go to repository" class="md-source" data-md-source="">
<div class="md-source__repository">
translate-yer-docs
</div>
</a>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container">
<main class="md-main">
<div class="md-main__inner md-grid" data-md-component="container">
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" data-md-level="0">
<label class="md-nav__title md-nav__title--site" for="__drawer">
<a href="https://pages.charlesreid1.com/translate-yer-docs" title="translate-yer-docs" class="md-nav__button md-logo">
<i class="md-icon">insert_drive_file arrow_right_alt g_translate arrow_right_alt insert_drive_file</i>
</a>
translate-yer-docs
</label>
<div class="md-nav__source">
<a href="https://git.charlesreid1.com/charlesreid1/translate-yer-docs" title="Go to repository" class="md-source" data-md-source="">
<div class="md-source__repository">
translate-yer-docs
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--active">
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
Home
</label>
<a href="." title="Home" class="md-nav__link md-nav__link--active">
Home
</a>
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#how-this-repo-is-organized" title="How This Repo is Organized" class="md-nav__link">
How This Repo is Organized
</a>
</li>
<li class="md-nav__item">
<a href="#part-1-google-cloud-translate-api-setup" title="Part 1: Google Cloud Translate API Setup" class="md-nav__link">
Part 1: Google Cloud Translate API Setup
</a>
</li>
<li class="md-nav__item">
<a href="#part-2-pandoc" title="Part 2: Pandoc" class="md-nav__link">
Part 2: Pandoc
</a>
</li>
<li class="md-nav__item">
<a href="#part-3-panflute" title="Part 3: Panflute" class="md-nav__link">
Part 3: Panflute
</a>
</li>
<li class="md-nav__item">
<a href="#part-4-pandoc" title="Part 4: Pandoc" class="md-nav__link">
Part 4: Pandoc
</a>
</li>
<li class="md-nav__item">
<a href="#part-5-testing" title="Part 5: Testing" class="md-nav__link">
Part 5: Testing
</a>
</li>
<li class="md-nav__item">
<a href="#part-6-useful-links" title="Part 6: Useful Links" class="md-nav__link">
Part 6: Useful Links
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="Organization/" title="How This Repo is Organized" class="md-nav__link">
How This Repo is Organized
</a>
</li>
<li class="md-nav__item">
<a href="Setup/" title="Setup" class="md-nav__link">
Setup
</a>
</li>
<li class="md-nav__item">
<a href="PandocA/" title="Pandoc: Markdown to JSON" class="md-nav__link">
Pandoc: Markdown to JSON
</a>
</li>
<li class="md-nav__item">
<a href="PandocB/" title="Pandoc: JSON to JSON" class="md-nav__link">
Pandoc: JSON to JSON
</a>
</li>
<li class="md-nav__item">
<a href="PanfluteA/" title="Panflute: Translate" class="md-nav__link">
Panflute: Translate
</a>
</li>
<li class="md-nav__item">
<a href="PanfluteB/" title="Panflute: Page Elements" class="md-nav__link">
Panflute: Page Elements
</a>
</li>
<li class="md-nav__item">
<a href="PandocC/" title="Pandoc: JSON to Markdown" class="md-nav__link">
Pandoc: JSON to Markdown
</a>
</li>
<li class="md-nav__item">
<a href="Testing/" title="Testing" class="md-nav__link">
Testing
</a>
</li>
<li class="md-nav__item">
<a href="Links/" title="Links" class="md-nav__link">
Links
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#how-this-repo-is-organized" title="How This Repo is Organized" class="md-nav__link">
How This Repo is Organized
</a>
</li>
<li class="md-nav__item">
<a href="#part-1-google-cloud-translate-api-setup" title="Part 1: Google Cloud Translate API Setup" class="md-nav__link">
Part 1: Google Cloud Translate API Setup
</a>
</li>
<li class="md-nav__item">
<a href="#part-2-pandoc" title="Part 2: Pandoc" class="md-nav__link">
Part 2: Pandoc
</a>
</li>
<li class="md-nav__item">
<a href="#part-3-panflute" title="Part 3: Panflute" class="md-nav__link">
Part 3: Panflute
</a>
</li>
<li class="md-nav__item">
<a href="#part-4-pandoc" title="Part 4: Pandoc" class="md-nav__link">
Part 4: Pandoc
</a>
</li>
<li class="md-nav__item">
<a href="#part-5-testing" title="Part 5: Testing" class="md-nav__link">
Part 5: Testing
</a>
</li>
<li class="md-nav__item">
<a href="#part-6-useful-links" title="Part 6: Useful Links" class="md-nav__link">
Part 6: Useful Links
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content">
<article class="md-content__inner md-typeset">
<h1 id="translate-yer-docs">translate yer docs<a class="headerlink" href="#translate-yer-docs" title="Permanent link">&para;</a></h1>
<p>This repository translates yer docs into another language.</p>
<p>This uses the Google Cloud Translate API,
pandoc, and the panflute library to create
a translation filter for Markdown files.</p>
<p>See an example here: <a href="https://pages.charlesreid1.com/russian-rainbow-mind-machine">russian-rainbow-mind-machine</a>
(page contains documentation for the <a href="https://pages.charlesreid1.com/b-rainbow-mind-machine">rainbow-mind-machine</a>
library translated into Russian).</p>
<h2 id="how-this-repo-is-organized">How This Repo is Organized<a class="headerlink" href="#how-this-repo-is-organized" title="Permanent link">&para;</a></h2>
<p><a href="Organization/">How this repo is organized</a></p>
<h2 id="part-1-google-cloud-translate-api-setup">Part 1: Google Cloud Translate API Setup<a class="headerlink" href="#part-1-google-cloud-translate-api-setup" title="Permanent link">&para;</a></h2>
<p>The Google Cloud Translate API is what makes this all possible.</p>
<p>It is easier to translate documentation into Russian
than it is to figure out how to parse Markdown programmatically
with panflute and pandocs.</p>
<p><a href="Setup/">Part 1: Setup</a></p>
<h2 id="part-2-pandoc">Part 2: Pandoc<a class="headerlink" href="#part-2-pandoc" title="Permanent link">&para;</a></h2>
<p>We want to parse and translate Markdown written
in English, and turn it into Markdown written in
Russian. We use pandoc to parse the Markdown file
and identify the bits that can be translated,
pass them to the Google Cloud Translate API,
and convert the translated text back into
Markdown.</p>
<p>Part 2: Pandoc:</p>
<p><a href="PandocA/">Pandoc: Markdown to JSON</a></p>
<p><a href="PandocB/">Pandoc: JSON to JSON</a></p>
<h2 id="part-3-panflute">Part 3: Panflute<a class="headerlink" href="#part-3-panflute" title="Permanent link">&para;</a></h2>
<p>Panflute is a Python library for writing Pandoc filters.
It is picky and tricky.</p>
<p>Part 3: Panflute:</p>
<p><a href="PanfluteA/">Panflute: Translate</a></p>
<p><a href="PanfluteB/">Panflute: Page Elements</a></p>
<h2 id="part-4-pandoc">Part 4: Pandoc<a class="headerlink" href="#part-4-pandoc" title="Permanent link">&para;</a></h2>
<p>The panflute filter will process JSON and return more JSON,
so we have one last step, which is converting the final
JSON document into Markdown.</p>
<p><a href="PandocC/">Part 4: Pandoc: JSON to Markdown</a></p>
<h2 id="part-5-testing">Part 5: Testing<a class="headerlink" href="#part-5-testing" title="Permanent link">&para;</a></h2>
<p>You do want to write tests for all of this stuff, don't you?</p>
<p><a href="Testing/">Part 5: Testing</a></p>
<h2 id="part-6-useful-links">Part 6: Useful Links<a class="headerlink" href="#part-6-useful-links" title="Permanent link">&para;</a></h2>
<p><a href="Links/">Part 6: Useful Links</a></p>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href="Organization/" title="How This Repo is Organized" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Next
</span>
How This Repo is Organized
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i>
</div>
</a>
</nav>
</div>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
<div class="md-footer-copyright__highlight">
Copyright &copy; 2018 <a href="https://charlesreid1.com">Charles Reid</a>, released under the <a href="https://opensource.org/licenses/MIT">MIT License</a>.
</div>
powered by
<a href="https://www.mkdocs.org">MkDocs</a>
and
<a href="https://squidfunk.github.io/mkdocs-material/">
Material for MkDocs</a>
</div>
</div>
</div>
</footer>
</div>
<script src="assets/javascripts/application.e72fd936.js"></script>
<script>app.initialize({version:"1.0",url:{base:"."}})</script>
<script src="search/main.js"></script>
</body>
</html>

1
mkdocs-material

@ -1 +0,0 @@
Subproject commit b0c6890853aa9138baf5f9749862b927518ab656

46
mkdocs.yml

@ -1,46 +0,0 @@
site_name: "translate-yer-docs"
site_url: https://pages.charlesreid1.com/translate-yer-docs
repo_name: translate-yer-docs
repo_url: https://git.charlesreid1.com/charlesreid1/translate-yer-docs
copyright: 'Copyright &copy; 2018 <a href="https://charlesreid1.com">Charles Reid</a>, released under the <a href="https://opensource.org/licenses/MIT">MIT License</a>.'
docs_dir: docs
site_dir: site
extra_css:
- css/custom.css
theme:
name: null
custom_dir: 'mkdocs-material/material'
palette:
primary: 'indigo'
accent: 'indigo'
logo:
icon: 'insert_drive_file arrow_right_alt g_translate arrow_right_alt insert_drive_file'
font:
text: 'Ubuntu'
code: 'Ubuntu Mono'
markdown_extensions:
- admonition
- codehilite:
guess_lang: false
- toc:
permalink: true
nav:
- 'Home': 'index.md'
- 'How This Repo is Organized' : 'Organization.md'
- 'Setup': 'Setup.md'
- 'Pandoc: Markdown to JSON' : 'PandocA.md'
- 'Pandoc: JSON to JSON' : 'PandocB.md'
- 'Panflute: Translate' : 'PanfluteA.md'
- 'Panflute: Page Elements' : 'PanfluteB.md'
- 'Pandoc: JSON to Markdown' : 'PandocC.md'
- 'Testing': 'Testing.md'
- 'Links': 'Links.md'
strict: true
strict: true

2986
search/lunr.js

File diff suppressed because it is too large Load Diff

94
search/main.js

@ -0,0 +1,94 @@
function getSearchTermFromLocation() {
var sPageURL = window.location.search.substring(1);
var sURLVariables = sPageURL.split('&');
for (var i = 0; i < sURLVariables.length; i++) {
var sParameterName = sURLVariables[i].split('=');
if (sParameterName[0] == 'q') {
return decodeURIComponent(sParameterName[1].replace(/\+/g, '%20'));
}
}
}
function formatResult (location, title, summary) {
return '<article><h3><a href="' + base_url + '/' + location + '">'+ title + '</a></h3><p>' + summary +'</p></article>';
}
function displayResults (results) {
var search_results = document.getElementById("mkdocs-search-results");
while (search_results.firstChild) {
search_results.removeChild(search_results.firstChild);
}
if (results.length > 0){
for (var i=0; i < results.length; i++){
var result = results[i];
var html = formatResult(result.location, result.title, result.summary);
search_results.insertAdjacentHTML('beforeend', html);
}
} else {
search_results.insertAdjacentHTML('beforeend', "<p>No results found</p>");
}
}
function doSearch () {
var query = document.getElementById('mkdocs-search-query').value;
if (query.length > 2) {
console.log('Searching with query: ' + query);
if (!window.Worker) {
displayResults(search(query));
} else {
searchWorker.postMessage({query: query});
}
} else {
// Clear results for short queries
displayResults([]);
}
}
function initSearch () {
var search_input = document.getElementById('mkdocs-search-query');
if (search_input) {
search_input.addEventListener("keyup", doSearch);
}
var term = getSearchTermFromLocation();
if (term) {
search_input.value = term;
doSearch();
}
}
function onWorkerMessage (e) {
if (e.data.results) {
var results = e.data.results;
displayResults(results);
}
}
if (!window.Worker) {
console.log('Web Worker API not supported');
// load index in main thread
$.getScript(base_url + "/search/worker.js").done(function () {
console.log('Loaded worker');
init();
}).fail(function (jqxhr, settings, exception) {
console.error('Could not load worker.js');
});
} else {
// Wrap search in a web worker
var searchWorker = new Worker(base_url + "/search/worker.js");
searchWorker.postMessage({init: true});
searchWorker.onmessage = onWorkerMessage;
}
$(function() {
var search_input = document.getElementById('mkdocs-search-query');
if (search_input) {
search_input.addEventListener("keyup", doSearch);
}
var term = getSearchTermFromLocation();
if (term) {
search_input.value = term;
doSearch();
}
});

1
search/search_index.json

File diff suppressed because one or more lines are too long

127
search/worker.js

@ -0,0 +1,127 @@
var base_path = 'function' === typeof importScripts ? '.' : '/search/';
var allowSearch = false;
var index;
var documents = {};
var lang = ['en'];
var data;
function getScript(script, callback) {
console.log('Loading script: ' + script);
$.getScript(base_path + script).done(function () {
callback();
}).fail(function (jqxhr, settings, exception) {
console.log('Error: ' + exception);
});
}
function getScriptsInOrder(scripts, callback) {
if (scripts.length === 0) {
callback();
return;
}
getScript(scripts[0], function() {
getScriptsInOrder(scripts.slice(1), callback);
});
}
function loadScripts(urls, callback) {
if( 'function' === typeof importScripts ) {
importScripts.apply(null, urls);
callback();
} else {
getScriptsInOrder(urls, callback);
}
}
function onJSONLoaded () {
data = JSON.parse(this.responseText);
var scriptsToLoad = ['lunr.js'];
if (data.config && data.config.lang && data.config.lang.length) {
lang = data.config.lang;
}
if (lang.length > 1 || lang[0] !== "en") {
scriptsToLoad.push('lunr.stemmer.support.js');
if (lang.length > 1) {
scriptsToLoad.push('lunr.multi.js');
}
for (var i=0; i < lang.length; i++) {
if (lang[i] != 'en') {
scriptsToLoad.push(['lunr', lang[i], 'js'].join('.'));
}
}
}
loadScripts(scriptsToLoad, onScriptsLoaded);
}
function onScriptsLoaded () {
console.log('All search scripts loaded, building Lunr index...');
if (data.config && data.config.separator && data.config.separator.length) {
lunr.tokenizer.separator = new RegExp(data.config.separator);
}
if (data.index) {
index = lunr.Index.load(data.index);
data.docs.forEach(function (doc) {
documents[doc.location] = doc;
});
console.log('Lunr pre-built index loaded, search ready');
} else {
index = lunr(function () {
if (lang.length === 1 && lang[0] !== "en" && lunr[lang[0]]) {
this.use(lunr[lang[0]]);
} else if (lang.length > 1) {
this.use(lunr.multiLanguage.apply(null, lang)); // spread operator not supported in all browsers: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator#Browser_compatibility
}
this.field('title');
this.field('text');
this.ref('location');
for (var i=0; i < data.docs.length; i++) {
var doc = data.docs[i];
this.add(doc);
documents[doc.location] = doc;
}
});
console.log('Lunr index built, search ready');
}
allowSearch = true;
}
function init () {
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", onJSONLoaded);
var index_path = base_path + '/search_index.json';
if( 'function' === typeof importScripts ){
index_path = 'search_index.json';
}
oReq.open("GET", index_path);
oReq.send();
}
function search (query) {
if (!allowSearch) {
console.error('Assets for search still loading');
return;
}
var resultDocuments = [];
var results = index.search(query);
for (var i=0; i < results.length; i++){
var result = results[i];
doc = documents[result.ref];
doc.summary = doc.text.substring(0, 200);
resultDocuments.push(doc);
}
return resultDocuments;
}
if( 'function' === typeof importScripts ) {
onmessage = function (e) {
if (e.data.init) {
init();
} else if (e.data.query) {
postMessage({ results: search(e.data.query) });
} else {
console.error("Worker - Unrecognized message: " + e);
}
};
}

53
sitemap.xml

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://pages.charlesreid1.com/translate-yer-docs/</loc>
<lastmod>2018-08-11</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://pages.charlesreid1.com/translate-yer-docs/Organization/</loc>
<lastmod>2018-08-11</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://pages.charlesreid1.com/translate-yer-docs/Setup/</loc>
<lastmod>2018-08-11</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://pages.charlesreid1.com/translate-yer-docs/PandocA/</loc>
<lastmod>2018-08-11</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://pages.charlesreid1.com/translate-yer-docs/PandocB/</loc>
<lastmod>2018-08-11</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://pages.charlesreid1.com/translate-yer-docs/PanfluteA/</loc>
<lastmod>2018-08-11</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://pages.charlesreid1.com/translate-yer-docs/PanfluteB/</loc>
<lastmod>2018-08-11</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://pages.charlesreid1.com/translate-yer-docs/PandocC/</loc>
<lastmod>2018-08-11</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://pages.charlesreid1.com/translate-yer-docs/Testing/</loc>
<lastmod>2018-08-11</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://pages.charlesreid1.com/translate-yer-docs/Links/</loc>
<lastmod>2018-08-11</lastmod>
<changefreq>daily</changefreq>
</url>
</urlset>

BIN
sitemap.xml.gz

Binary file not shown.

67
source/index.md

@ -1,67 +0,0 @@
# rainbow-mind-machine
![tinysheep](sheep.jpg)
**rainbow mind machine** is an extensible framework for running Twitter bot flocks in Python.
rainbow mind machine helps with managing multiple twitter bots (bot flocks).
It uses a Keymaker object to do the one-time authentication step with Twitter,
and uses a Shepherd-Sheep model to run the flock.
rainbow mind machine is a **framework** because it provides components
([Keymaker](keymaker.md), [Shepherd](shepherd.md), and [Sheep](sheep.md))
with specific roles and ways of interacting.
rainbow mind machine is **extensible** to keep bots from becoming boring.
There are a limited number of components to extend (2),
these two components have a simple and clear function call order,
and rainbow mind machine tries to use sensible defaults.
That means we start out with bots that "just work"
and we can incrementally improve, extend, override,
or redefine behaviors to make them increasingly complex,
while still abstracting away messy details.
## Useful links
[rainbow mind machine documentation on charlesreid1.com (you are here)](https://pages.charlesreid1.com/b-rainbow-mind-machine)
source code:
[rainbow mind machine source code on git.charlesreid1.com](https://git.charlesreid1.com/bots/b-rainbow-mind-machine)
[rainbow mind machine source code on github.com/rainbow-mind-machine/rainbow-mind-machine](https://github.com/rainbow-mind-machine/rainbow-mind-machine)
packaged products:
[rainbow mind machine package on pypi](https://pypi.org/project/rainbowmindmachine/) (`pip install rainbowmindmachine`)
[rainbow mind machine on dockerhub](https://hub.docker.com/r/rainbowmindmachine/rainbowmindmachine/) (`docker pull rainbowmindmachine/rainbowmindmachine`)
related projects:
[rainbow mind machine organization on github](https://github.com/rainbow-mind-machine)
## Installing rainbow mind machine
See [installing](/installing.md) for installation instructions.
## Quick Start
See [quickstart](/quickstart.md) for a quick guide to
getting a bot up and running, and a few bot flock examples.
## Docker
See [docker](/docker.md) for more information about
using rainbow mind machine in a docker container.
## Dev Workflow
See [dev-workflow](/dev-workflow.md) for info about the workflow for
uploading changes to pypi and dockerhub.
## Get In Touch
Contact the author: `rainbowmindmachine@charlesreid1.com`

BIN
source/sheep.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

BIN
source/shepherd.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

165
source/shepherd.md

@ -1,165 +0,0 @@
# The Shepherd
![the shepherd](shepherd.jpg)
**The rainbow mind machine shepherd. [credit](credits.md)**
## what is the Shepherd?
The Shepherd is a very simple object.
The Shepherd is a data container for storing Sheep.
## when does the Shepherd come in?
The first thing a bot flock needs is a set of keys.
That's what the [Keymaker](keymaker.md) is for.
Once the bot flock keys have been created with the Keymaker,
the bot flock is started. To do that, the Shepherd
initializes each Sheep with a corresponding JSON
key file (created by the Keymaker).
## how does the Shepherd tend to the Sheep?
In general, the Shepherd is a free-range parent, and lets the
Sheep go off and do their own thing.
Note however, that in the spirit of extensibility,
you can extend the Shepherd and Sheep classes to
change the nature of your bot flock.
(See next section.)
## when and how do you extend the Shepherd?
The Shepherd class determines how much coordination
happens among different Sheep in the flock and between
the flock and the outside world (the Internet).
Let's look at some simple examples of when you would
need to extend the Shepherd class, and what modifications
would be required.
### storing custom parameters
First, let's mention a feature of the Shepherd
that makes adding new parameters to extended versions
of the Shepherd class really simple.
The Shepherd constructor `__init__()` includes a
`**kwargs` argument at the end. This will create a
dictionary called `kwargs` with any key-value pairs
the user passed in. This is stored in `self.params`
at the end of the constructor:
```
self.params = kwargs
```
This means that if you create a new Shepherd class
like `CarMechanicShepherd`, and you need to pass in
(say) a boolean input parameter like `uses_metric`,
you don't have to explicitly modify the constructor
to take `uses_metric` as a parameter;
the Shepherd class automatically adds
a key `uses_metric` with a value `True||False`
to a dictionary `self.params` when you
call the constructor like
```
CarMechanicShepherd(uses_metric=False)
```
Okay, back to the regularly scheduled program...
### webhook bot flock
As an example of a bot flock that requires tighter integration
between the Shepherd and the Sheep, imagine you want to create
a bot fock where the bots can be controlled with webhooks.
You would need the Shepherd to act as a central dispatcher
and process incoming webhooks to determine which webhook
payloads to pass on to which Sheep. But the Sheep also need
to be modified to listen for instructions from the Shepherd.
To modify the Shepherd class, we would add a method
that listens for incoming webhooks, and a method or
methods implementing logic about which payloads to
pass along to which Sheep (or to call the appropriate
functions when webhooks trigger flock-wide actions).
To modify the Sheep class, we would add a `listen()` method
that would run forever - ideally in parallel with other
run-forever methods.
### two bots per key flock
Suppose we wanted to build an argument bot flock.
This bot flock would consist of pairs of Sheep
that use Queneau generation to create dialogue,
and that argue back and forth forever with each other.
This bot flock modifies the way that our Sheep
coordinate with each other, which is an indication
we should change the Shepherd class.
The Sheep bots we will use will work identically to
a normal Queneau Sheep bot. Each bot generates dialogue
from a single speaker, and tweets it in response to
another bot tweeting.
While we can extend the Sheep class to make it easier
to set fine grained controls over the dialogue process,
we can use the existing inner-outer loop structure
of Queneau bots to accomplish our goal.
So, Sheep do not require any extending.
The Shepherd class needs to be modified by changing
the way it instantiates bots from keys. Instead of
creating one bot per key, it should create two
bots per keys.
(Note that the user will need to provide relevant
details in the key or config dictionaries. For example,
name and handle of both bot sides, inner/outer loop timing,
etc.)
The `-setup_keys()` method will not change, because
we want to maintain the consistency of one key file
corresponding to one bot corresponding to one Twitter
account.
The `_setup_sheep()` method would be modified from
its current arrangement (pseudocode):
```
current _setup_sheep() method:
for json in list-of-all-json-files:
create new sheep from json
add new sheep to flock
```
to something more like (pseudocode):
```
new _setup_sheep() method:
for (bot1, bot2) in list-of-all-bot-pairs:
get key1 from keys
create bot1 from key1
get key2 from keys
create bot2 from key2
link bot1 and bot2
add bot1 and bot2 to flock
```
In this case, we want to have two Queneau Sheep that
work almost exactly the same as normal Queneau Sheep,
with perhaps a slight modification to make sure that
each bot generates dialogue from a single speaker
corresponding to their party in the argument.

79
translate

@ -1,79 +0,0 @@
#!/usr/bin/env python
import os, glob, subprocess
"""
Translate Pipeline Using Pandoc
Use glob to find all markdown files in `rmm/docs/`
For each one, run the pipeline using subprocess:
- run pipeline on each document in `rmm/docs/`
- pandoc markdown-to-json
- panflute filter to translate json and extract links
- pandoc json-to-markdown
- output documents in translated_docs/
TODO:
- call the pandoc API directly to avoid subprocess
"""
SOURCE_DOCS = 'rmm/docs'
TARGET_DOCS = 'ruskie_docs'
TRANSLATE_FILTER = 'filters/translate.py'
if not os.path.isdir(os.path.join(os.getcwd(),SOURCE_DOCS)):
err = "ERROR: No rmm/docs/ folder was found.\n"
err += "Looked in %s\n"%(os.path.join(os.getcwd(),SOURCE_DOCS))
err += "Try cloning with --recursive,\n"
err += "or running git submodule update --init\n"
raise Exception(err)
cwd = os.getcwd()
print("[+] Welcome to translate the docs!")
print("[+] Making directory for translated documentation: %s"%(TARGET_DOCS))
subprocess.call(['mkdir','-p',TARGET_DOCS], cwd=cwd)
markdown_files = []
for fdir,fdirnames,fnames in os.walk(os.path.join(os.getcwd(),SOURCE_DOCS)):
for f in fnames:
if f[-3:]=='.md':
markdown_files.append( os.path.join( fdir, f ) )
for en_md in markdown_files:
basename = os.path.split(en_md)[-1]
target = os.path.join(TARGET_DOCS,basename)
pname = os.path.join(SOURCE_DOCS,basename)
print(" [+] Now making documentation for %s to %s"%(pname,target))
# Command 1:
# cat <md>
cat_cmd = ['cat', en_md]
cat_proc = subprocess.Popen(cat_cmd, stdout=subprocess.PIPE)
# pandoc: english markdown to json
# -f from_format
# -t to_format
pandoc_from_en_cmd = ['pandoc','-f','gfm','-t','json','-s']
pandoc_from_en_proc = subprocess.Popen(pandoc_from_en_cmd, stdin=cat_proc.stdout, stdout=subprocess.PIPE)
# pandoc filter to translate with google cloud
pandoc_filter_cmd = [TRANSLATE_FILTER]
pandoc_filter_proc = subprocess.Popen(pandoc_filter_cmd, stdin=pandoc_from_en_proc.stdout, stdout=subprocess.PIPE)
# pandoc: json to translated markdown
pandoc_to_ru_cmd = ['pandoc','-f','json','-t','gfm']
pandoc_to_ru_proc = subprocess.Popen(pandoc_to_ru_cmd, stdin=pandoc_filter_proc.stdout, stdout=subprocess.PIPE)
with open(target,'wb') as f:
f.write(pandoc_to_ru_proc.stdout.read())
print(" [+] Finished with file %s, translated to %s"%(pname,target))
print("[+] All done!")
Loading…
Cancel
Save