Latest changes (and mirror testing)
This commit is contained in:
parent
0df1699c27
commit
f1f1be481a
|
@ -1,6 +1,6 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (C) 2018 Thomas Touhey <thomas@touhey.fr>
|
||||
Copyright (C) 2018-2019 Thomas Touhey <thomas@touhey.fr>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the “Software”), to deal
|
||||
|
|
2
Makefile
2
Makefile
|
@ -4,7 +4,7 @@
|
|||
DNAME := dist/$(shell $(ST) --name)-$(shell $(ST) --version).tar.gz
|
||||
|
||||
test tests:
|
||||
@$(ST) test
|
||||
@$(PE) pytest -s -q
|
||||
|
||||
prepare:
|
||||
@pipenv install --dev
|
||||
|
|
3
Pipfile
3
Pipfile
|
@ -8,9 +8,10 @@ python_version = '3.7'
|
|||
|
||||
[packages]
|
||||
regex = '*'
|
||||
thcolor = { git = 'https://forge.touhey.org/thcolor.git' }
|
||||
thcolor = '*'
|
||||
|
||||
[dev-packages]
|
||||
sphinx = '*'
|
||||
"collective.checkdocs" = '*'
|
||||
pudb = '*'
|
||||
pytest = '*'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "6505cb754ffede68e416ce5cf702dddf8f956a3181a4d58924aff57847b29ee9"
|
||||
"sha256": "f2cea3a09ae48de290ab5aa3af45cedaf158f9586a8f84c50c1825de25732522"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
|
@ -32,8 +32,11 @@
|
|||
"version": "==2019.4.14"
|
||||
},
|
||||
"thcolor": {
|
||||
"git": "https://forge.touhey.org/thcolor.git",
|
||||
"ref": "be32e9875ea503dd80bc00abaff12727fdb6c645"
|
||||
"hashes": [
|
||||
"sha256:a93a535f7f81b5e38460531b5731f0fa8c4b30b2a63d1fe763c2ac15e37df8b7"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.3.1"
|
||||
}
|
||||
},
|
||||
"develop": {
|
||||
|
@ -44,6 +47,20 @@
|
|||
],
|
||||
"version": "==0.7.12"
|
||||
},
|
||||
"atomicwrites": {
|
||||
"hashes": [
|
||||
"sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4",
|
||||
"sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6"
|
||||
],
|
||||
"version": "==1.3.0"
|
||||
},
|
||||
"attrs": {
|
||||
"hashes": [
|
||||
"sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79",
|
||||
"sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399"
|
||||
],
|
||||
"version": "==19.1.0"
|
||||
},
|
||||
"babel": {
|
||||
"hashes": [
|
||||
"sha256:6778d85147d5d85345c14a26aada5e478ab04e39b078b0745ee6870c2b5cf669",
|
||||
|
@ -134,6 +151,14 @@
|
|||
],
|
||||
"version": "==1.1.1"
|
||||
},
|
||||
"more-itertools": {
|
||||
"hashes": [
|
||||
"sha256:2112d2ca570bb7c3e53ea1a35cd5df42bb0fd10c45f0fb97178679c3c03d64c7",
|
||||
"sha256:c3e4748ba1aad8dba30a4886b0b1a2004f9a863837b8654e7059eebf727afa5a"
|
||||
],
|
||||
"markers": "python_version > '2.7'",
|
||||
"version": "==7.0.0"
|
||||
},
|
||||
"packaging": {
|
||||
"hashes": [
|
||||
"sha256:0c98a5d0be38ed775798ece1b9727178c4469d9c3b4ada66e8e6b7849f8732af",
|
||||
|
@ -141,6 +166,13 @@
|
|||
],
|
||||
"version": "==19.0"
|
||||
},
|
||||
"pluggy": {
|
||||
"hashes": [
|
||||
"sha256:25a1bc1d148c9a640211872b4ff859878d422bccb59c9965e04eed468a0aa180",
|
||||
"sha256:964cedd2b27c492fbf0b7f58b3284a09cf7f99b0f715941fb24a439b3af1bd1a"
|
||||
],
|
||||
"version": "==0.11.0"
|
||||
},
|
||||
"pudb": {
|
||||
"hashes": [
|
||||
"sha256:ac30cfc64580958ab7265decb4cabb9141f08781ff072e9a336d5a7942ce35a6"
|
||||
|
@ -148,12 +180,19 @@
|
|||
"index": "pypi",
|
||||
"version": "==2019.1"
|
||||
},
|
||||
"py": {
|
||||
"hashes": [
|
||||
"sha256:64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa",
|
||||
"sha256:dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53"
|
||||
],
|
||||
"version": "==1.8.0"
|
||||
},
|
||||
"pygments": {
|
||||
"hashes": [
|
||||
"sha256:5ffada19f6203563680669ee7f53b64dabbeb100eb51b61996085e99c03b284a",
|
||||
"sha256:e8218dd399a61674745138520d0d4cf2621d7e032439341bc3f647bff125818d"
|
||||
"sha256:31cba6ffb739f099a85e243eff8cb717089fdd3c7300767d9fc34cb8e1b065f5",
|
||||
"sha256:5ad302949b3c98dd73f8d9fcdc7e9cb592f120e32a18e23efd7f3dc51194472b"
|
||||
],
|
||||
"version": "==2.3.1"
|
||||
"version": "==2.4.0"
|
||||
},
|
||||
"pyparsing": {
|
||||
"hashes": [
|
||||
|
@ -162,6 +201,14 @@
|
|||
],
|
||||
"version": "==2.4.0"
|
||||
},
|
||||
"pytest": {
|
||||
"hashes": [
|
||||
"sha256:1a8aa4fa958f8f451ac5441f3ac130d9fc86ea38780dd2715e6d5c5882700b24",
|
||||
"sha256:b8bf138592384bd4e87338cb0f256bf5f615398a649d4bd83915f0e4047a5ca6"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.5.0"
|
||||
},
|
||||
"pytz": {
|
||||
"hashes": [
|
||||
"sha256:303879e36b721603cc54604edcac9d20401bdbe31e1e4fdee5b9f98d5d31dfda",
|
||||
|
@ -252,6 +299,13 @@
|
|||
"sha256:644d3e3900867161a2fc9287a9762753d66bd194754679adb26aede559bcccbc"
|
||||
],
|
||||
"version": "==2.0.1"
|
||||
},
|
||||
"wcwidth": {
|
||||
"hashes": [
|
||||
"sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e",
|
||||
"sha256:f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c"
|
||||
],
|
||||
"version": "==0.1.7"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
33
README.rst
33
README.rst
|
@ -7,27 +7,28 @@ documentation accessible on `the official website`_.
|
|||
|
||||
.. warning::
|
||||
|
||||
If you are accessing this repository from `Planète Casio's forge`_,
|
||||
If you are accessing this repository from another forge (such as
|
||||
`Planète Casio's forge <https://gitea.planet-casio.com/>`_),
|
||||
keep in mind that it is only a mirror and that the real repository
|
||||
is located `in my forge <Thomas' forge_>`_ for now.
|
||||
|
||||
What is left to do
|
||||
------------------
|
||||
For example, if we want to translate some basic multi-block text to HTML:
|
||||
|
||||
- Add an ``[imgurl]`` tag?
|
||||
- Manage lightscript (or even markdown?) as output languages;
|
||||
- Check where the errors are to display them to the user:
|
||||
.. code-block:: python
|
||||
|
||||
* Count character offset, line number and column number in the lexer;
|
||||
* Produce readable exceptions;
|
||||
* Make a clean interface to transmit them;
|
||||
- Check why exceptions on raw tags effectively escape the content, as it
|
||||
shouldn't…?
|
||||
- Look for security flaws (we really don't want stored XSS flaws!).
|
||||
- Implement match names (such as ``\[\*+\]`` for lists).
|
||||
- Manage keywords with tags such as ``[tag key=value other="something else"]``.
|
||||
from textoutpc import tohtml
|
||||
|
||||
text = """[img=center]https://www.planet-casio.com/skins/bootstrap/img/default/logo.png[/img]
|
||||
|
||||
Hello [color=R10]world[/color]!
|
||||
[ul]
|
||||
[*]This module is made by [url=https://thomas.touhey.fr/]Thomas Touhey[/url]!
|
||||
[*]Use `.tohtml()` to translate magically to HTML!
|
||||
[/]
|
||||
"""
|
||||
|
||||
print(tohtml(text))
|
||||
|
||||
.. _Planète Casio: https://www.planet-casio.com/
|
||||
.. _Planète Casio's forge: https://gitea.planet-casio.com/
|
||||
.. _Thomas' forge: https://forge.touhey.fr/pc/textout.git
|
||||
.. _the official website: https://textout.touhey.fr/
|
||||
.. _the official website: https://textout.touhey.pro/
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
What is left to do
|
||||
==================
|
||||
|
||||
- Add an ``[imgurl]`` tag?
|
||||
- Manage lightscript (or even markdown?) as output languages;
|
||||
- Check where the errors are to display them to the user:
|
||||
|
||||
* Count character offset, line number and column number in the lexer;
|
||||
* Produce readable exceptions;
|
||||
* Make a clean interface to transmit them;
|
||||
- Check why exceptions on raw tags effectively escape the content, as it
|
||||
shouldn't…?
|
||||
- Look for security flaws (we really don't want stored XSS flaws!).
|
||||
- Implement match names (such as ``\[\*+\]`` for lists).
|
||||
- Manage keywords with tags such as ``[tag key=value other="something else"]``.
|
38
docs/conf.py
38
docs/conf.py
|
@ -11,22 +11,33 @@
|
|||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
# import os
|
||||
# import sys
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
def _add_paths():
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.abspath('..'))
|
||||
|
||||
_add_paths()
|
||||
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = 'textoutpc'
|
||||
copyright = '2018, Thomas Touhey'
|
||||
copyright = '2019, Thomas Touhey'
|
||||
author = 'Thomas Touhey'
|
||||
|
||||
# The short X.Y version
|
||||
version = ''
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = ''
|
||||
|
||||
def _get_release():
|
||||
from os.path import dirname, join
|
||||
from pkg_resources import find_distributions as find_dist
|
||||
|
||||
module_path = join(dirname(__file__), '..')
|
||||
dist = next(find_dist(module_path, True))
|
||||
return dist.version
|
||||
|
||||
release = _get_release()
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
@ -39,10 +50,11 @@ release = ''
|
|||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc'
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
templates_path = []
|
||||
|
||||
# The suffix(es) of source filenames.
|
||||
# You can specify multiple suffix as a list of string:
|
||||
|
@ -63,7 +75,7 @@ language = None
|
|||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This pattern also affects html_static_path and html_extra_path .
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '.goutput*']
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
@ -74,7 +86,7 @@ pygments_style = 'sphinx'
|
|||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
html_theme = 'alabaster'
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
|
@ -85,7 +97,7 @@ html_theme = 'alabaster'
|
|||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
html_static_path = []
|
||||
|
||||
# Custom sidebar templates, must be a dictionary that maps document names
|
||||
# to template names.
|
||||
|
@ -152,4 +164,4 @@ texinfo_documents = [
|
|||
(master_doc, 'textoutpc', 'textoutpc Documentation',
|
||||
author, 'textoutpc', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
]
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
name = textoutpc
|
||||
version = attr: textoutpc.version
|
||||
url = https://textout.touhey.pro/
|
||||
project_urls =
|
||||
Documentation = https://textout.touhey.pro/docs/
|
||||
author = Thomas Touhey
|
||||
author_email = thomas@touhey.fr
|
||||
description = textout() equivalent from Planète Casio
|
||||
|
@ -42,3 +44,7 @@ universal = True
|
|||
[flake8]
|
||||
ignore = F401, F403, E128, E131, E241, E261, E265, E271, W191
|
||||
exclude = .git, __pycache__, build, dist, docs/conf.py, test.py, test
|
||||
|
||||
[tool:pytest]
|
||||
python_files = tests.py test_*.py *_tests.py
|
||||
testpaths = tests
|
||||
|
|
232
test/html.py
232
test/html.py
|
@ -1,232 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
#******************************************************************************
|
||||
# Copyright (C) 2018 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
||||
# This file is part of the textoutpc project, which is MIT-licensed.
|
||||
#******************************************************************************
|
||||
""" Unit tests for the Python version of textout.
|
||||
Uses the builtin `unittest` module.
|
||||
"""
|
||||
|
||||
import unittest as _unittest
|
||||
|
||||
__all__ = ["TextoutHTMLTest"]
|
||||
|
||||
# Define the tests.
|
||||
|
||||
__test_cases = {
|
||||
# Basic text.
|
||||
'': '',
|
||||
'lol': '<p>lol</p>',
|
||||
'<script>alert(1);</script>': \
|
||||
'<p><script>alert(1);</script></p>',
|
||||
|
||||
# Other tests. (?)
|
||||
'[a][c][/a]': '<p>[a][c][/a]</p>',
|
||||
'[a][a]': '<p>[a][a]</p>',
|
||||
"[<>]><[/<>]": "<p>[<>]><[/<>]</p>",
|
||||
|
||||
# Autolinking.
|
||||
'(http://www.example.org/some-[damn-url]-(youknow))': \
|
||||
'<p>(<a href="http://www.example.org/some-[damn-url]-(youknow)">' \
|
||||
'http://www.example.org/some-[damn-url]-(youknow)</a>)</p>',
|
||||
'https://thomas.touhey.fr/, tu vois ?': \
|
||||
'<p><a href="https://thomas.touhey.fr/">https://thomas.touhey.fr/' \
|
||||
'</a>, tu vois ?</p>',
|
||||
|
||||
# Basic text styling.
|
||||
'[u][b][a][i][/b]': "<p><u><b>[a]</b></u></p>",
|
||||
'[u][b]a[/]mdr': '<p><u><b>a</b>mdr</u></p>',
|
||||
|
||||
# Blocks, alignment.
|
||||
'[left]': '',
|
||||
'[left]lol[/]hi': '<div class="align-left"><p>lol</p></div><p>hi</p>',
|
||||
'a[justify]b': '<p>a</p><div class="align-justify"><p>b</p></div>',
|
||||
'a[i]': '<p>a</p>',
|
||||
'a[i][justify]b': '<p>a</p>' \
|
||||
'<div class="align-justify"><p><i>b</i></p></div>',
|
||||
'a[i]k[center]b': '<p>a<i>k</i></p>' \
|
||||
'<div class="align-center"><p><i>b</i></p></div>',
|
||||
'a[i]k[center][b]b[justify]c[/center]d[/]wouhou': \
|
||||
'<p>a<i>k</i></p>' \
|
||||
'<div class="align-center"><p><i><b>b</b></i></p>' \
|
||||
'<div class="align-justify"><p><i><b>c</b></i></p></div></div>' \
|
||||
'<p><i>d</i>wouhou</p>',
|
||||
|
||||
# Show tag for super preprocessing blocks.
|
||||
'[show]lol': '<p><span class="inline-code">lol</span></p>',
|
||||
'[quote][show][justify]hehe': \
|
||||
'<div class="citation"><p><span class="inline-code">' \
|
||||
'<div class="align-justify">' \
|
||||
'<p>hehe</p></div>' \
|
||||
'</span></p></div>',
|
||||
|
||||
# Titles.
|
||||
'lolk[title]smth': '<p>lolk</p>' '<h1 class="title">smth</h1>',
|
||||
'[subtitle]<>': '<h2 class="subtitle"><></h2>',
|
||||
|
||||
# Fonts.
|
||||
'[arial]test': '<p><span style="font-family: arial">test</span></p>',
|
||||
'[font=mono]stereo': \
|
||||
'<p><span style="font-family: monospace">stereo</span></p>',
|
||||
'[haettenschweiler]': '',
|
||||
'[font=hello]yea': '<p>[font=hello]yea</p>',
|
||||
|
||||
# Color.
|
||||
'yea[color=blue]dabadee': \
|
||||
'<p>yea<span style="color: #0000FF">dabadee</span></p>',
|
||||
'[color=#12345F]a': '<p><span style="color: #12345F">a</span></p>',
|
||||
'[color=#123]a': '<p><span style="color: #112233">a</span></p>',
|
||||
'[color=123]a': '<p><span style="color: #010203">a</span></p>',
|
||||
'[color=chucknorris]a': '<p><span style="color: #C00000">a</span></p>',
|
||||
'[color=rgb(1, 22,242)]a': '<p><span style="color: #0116F2">a</span></p>',
|
||||
'[color= rgb (1,22, 242 , 50.0% )]a': '<p><span style="color: #0116F2; ' \
|
||||
'color: rgba(1, 22, 242, 0.5)">a</span></p>',
|
||||
'[color=rgba(1,22,242,0.500)]a': '<p><span style="color: #0116F2; ' \
|
||||
'color: rgba(1, 22, 242, 0.5)">a</span></p>',
|
||||
'[color=rbga(5, 7)]b': '<p><span style="color: #050007">b</span></p>',
|
||||
'[color=hsl(0, 1,50.0%)]r': '<p><span style="color: #FF0000">r</span></p>',
|
||||
# TODO: hls, hwb
|
||||
|
||||
# Links.
|
||||
'[url]': '<p>[url]</p>',
|
||||
'[url=https://thomas.touhey.fr/]mon profil est le meilleur[/url]':
|
||||
'<p><a href="https://thomas.touhey.fr/">mon profil est le meilleur' \
|
||||
'</a></p>',
|
||||
'[url=https://thomas.touhey.fr/]': \
|
||||
'<p><a href="https://thomas.touhey.fr/">https://thomas.touhey.fr/' \
|
||||
'</a></p>',
|
||||
'[url=http://hey.org/lol[]>"a]': '<p><a href="http://hey.org/lol[]>' \
|
||||
'"a">' \
|
||||
'http://hey.org/lol[]>"a</a></p>',
|
||||
'[url]javascript:alert(1)[/url]': '<p>[url]javascript:alert(1)[/url]</p>',
|
||||
'[url]<script>alert(1);</script>[/url]': \
|
||||
'<p>[url]<script>alert(1);</script>[/url]</p>',
|
||||
|
||||
'[profil]cake[/profil]': \
|
||||
'<p><a href="https://www.planet-casio.com/Fr/compte/voir_profil.php' \
|
||||
'?membre=cake">cake</a></p>',
|
||||
'[profile]ekac': \
|
||||
'<p><a href="https://www.planet-casio.com/Fr/compte/voir_profil.php' \
|
||||
'?membre=ekac">ekac</a></p>',
|
||||
|
||||
# Quotes.
|
||||
'[quote]': '',
|
||||
'[quote]a': \
|
||||
'<div class="citation"><p>a</p></div>',
|
||||
'[quote=Test 1 :)]lel[/quote]': \
|
||||
'<div class="citation"><p><b>Test 1 ' \
|
||||
'<img src="/images/smileys/smile.gif"> a écrit :</b></p><p>' \
|
||||
'lel</p></div>',
|
||||
|
||||
# Spoilers.
|
||||
'[spoiler]': '',
|
||||
'[spoiler=Hello|world> :D]Close this, quick![/spoiler]': \
|
||||
'<div class="spoiler"><div class="title on" ' \
|
||||
'onclick="toggleSpoiler(this.parentNode, ' "'open'" ');"><p>Hello' \
|
||||
'</p></div><div class="title off" ' \
|
||||
'onclick="toggleSpoiler(this.parentNode, ' "'close'" ');"><p>world' \
|
||||
'> <img src="/images/smileys/grin.gif"></p></div>' \
|
||||
'<div class="off"><p>Close this, quick!</p></div></div>',
|
||||
|
||||
# Code.
|
||||
'[code]': '',
|
||||
"`[code]`": '<p><span class="inline-code">[code]</span></p>',
|
||||
|
||||
'[inlinecode]': '',
|
||||
"[inlinecode]`[/inlinecode]": '<p><span class="inline-code">`</span></p>',
|
||||
|
||||
"[b]a[noeval]b[/b]c[/noeval]d": "<p><b>ab[/b]cd</b></p>",
|
||||
"a[noeval]b[noeval]c[/noeval]d[/noeval]e": "<p>ab[noeval]c[/noeval]de</p>",
|
||||
"[noeval]``[/noeval]": "<p>``</p>",
|
||||
'[noeval]<>[/noeval]': '<p><></p>',
|
||||
|
||||
# Pictures.
|
||||
'[img]': '<p>[img]</p>',
|
||||
'[img]"incroyable<>"[/img]': \
|
||||
'<p>[img]"incroyable<>"[/img]</p>',
|
||||
'[img=right|float|12x345]https://example.org/image.png': \
|
||||
'<img src="https://example.org/image.png" class="img-float-right" ' \
|
||||
'style="width: 12px; height: 345px" />',
|
||||
|
||||
# Videos.
|
||||
'[video]"><script>alert(1)</script>[/video]': \
|
||||
'<p>[video]"><script>alert(1)</script>' \
|
||||
'[/video]</p>',
|
||||
'[video]<script>alert(document.cookie)</script>[/video]': \
|
||||
'<p>[video]<script>alert(document.cookie)</script>' \
|
||||
'[/video]</p>',
|
||||
'[video]https://www.youtube.com/watch?v=6odDOOyUawY[/video]': \
|
||||
'<div class="video-wrapper" style="padding-bottom: 56.25%"><iframe ' \
|
||||
'src="https://www.youtube.com/embed/6odDOOyUawY" ' \
|
||||
'frameborder="0" allowfullscreen></iframe></div>',
|
||||
'[video]https://www.youtube.com/watch?v=<script>alert(1)</script>': \
|
||||
'<p><a href="https://www.youtube.com/watch?v=<script>alert(1)' \
|
||||
'</script>">' \
|
||||
'https://www.youtube.com/watch?v=<script>alert(1)' \
|
||||
'</script></a></p>',
|
||||
'[video=left|float|4:3]https://www.youtube.com/watch?v=XEjLoHdbVeE': \
|
||||
'<div class="video-wrapper img-float-left" ' \
|
||||
'style="padding-bottom: 75%"><iframe ' \
|
||||
'src="https://www.youtube.com/embed/XEjLoHdbVeE" frameborder="0" ' \
|
||||
'allowfullscreen></iframe></div>',
|
||||
'lol[youtube]h4WLX8hfpJw': '<p>lol</p><div class="video-wrapper" ' \
|
||||
'style="padding-bottom: 56.25%"><iframe ' \
|
||||
'src="https://www.youtube.com/embed/h4WLX8hfpJw" frameborder="0" ' \
|
||||
'allowfullscreen></iframe></div>',
|
||||
|
||||
'[color=blue][youtube]h4WLX8hfpJw': \
|
||||
'<div class="video-wrapper" style="padding-bottom: 56.25%">' \
|
||||
'<iframe src="https://www.youtube.com/embed/h4WLX8hfpJw" ' \
|
||||
'frameborder="0" allowfullscreen></iframe></div>',
|
||||
'[color=blue]oh[youtube]h4WLX8hfpJw': \
|
||||
'<p><span style="color: #0000FF">oh</span></p>' \
|
||||
'<div class="video-wrapper" style="padding-bottom: 56.25%"><iframe ' \
|
||||
'src="https://www.youtube.com/embed/h4WLX8hfpJw" frameborder="0" ' \
|
||||
'allowfullscreen></iframe></div>',
|
||||
|
||||
# Progress bars.
|
||||
'[progress=lol]mdr[/progress]': '<p>[progress=lol]mdr[/progress]</p>',
|
||||
|
||||
# Text rotation obfuscation.
|
||||
'[rot13]obawbhe[/rot13]': '<p>bonjour</p>',
|
||||
|
||||
# Lists.
|
||||
'[list]haha[b][*]wow[*]incredible[/b][/*]wow[*]yuy[/list]': \
|
||||
'<ul><li><p>wow</p></li><li><p>incredible[/b]</p></li>' \
|
||||
'<li><p>yuy</p></li></ul>',
|
||||
'[list]\n[*]bonjour': '<ul><li><p>bonjour</p></li></ul>',
|
||||
|
||||
# Smileys.
|
||||
':)': '<p><img src="/images/smileys/smile.gif"></p>',
|
||||
':):)': '<p>:):)</p>',
|
||||
':) :D': '<p><img src="/images/smileys/smile.gif"> ' \
|
||||
'<img src="/images/smileys/grin.gif"></p>',
|
||||
}
|
||||
|
||||
# Define the tests wrapper, and define the classes.
|
||||
|
||||
_cnt = 0
|
||||
_len = len(str(len(__test_cases)))
|
||||
_templ = """\
|
||||
def test_html{n:0>{l}}(self):
|
||||
import textoutpc as _textoutpc
|
||||
self.assertEqual(_textoutpc.tohtml({i}), {r}, \\
|
||||
"for the following text: " + {i})
|
||||
"""
|
||||
|
||||
def _wrap_test(inp, res):
|
||||
global _cnt
|
||||
|
||||
_cnt += 1
|
||||
return _templ.format(n = _cnt, l = _len, i = repr(inp), r = repr(res))
|
||||
|
||||
exec("class TextoutHTMLTest(_unittest.TestCase):\n maxDiff = None\n" + \
|
||||
'\n'.join(map(lambda args: _wrap_test(*args), __test_cases.items())),
|
||||
globals())
|
||||
|
||||
# If run as main script, run the test function.
|
||||
|
||||
if __name__ == '__main__':
|
||||
_unittest.main()
|
||||
|
||||
# End of file.
|
|
@ -1,55 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
#******************************************************************************
|
||||
# Copyright (C) 2018 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
||||
# This file is part of the textoutpc project, which is MIT-licensed.
|
||||
#******************************************************************************
|
||||
""" Unit tests for the Python version of textout.
|
||||
Uses the builtin `unittest` module.
|
||||
"""
|
||||
|
||||
import unittest as _unittest
|
||||
|
||||
__all__ = ["TextoutHTMLiTest"]
|
||||
|
||||
# Define the tests.
|
||||
|
||||
__test_cases = {
|
||||
# Basic text.
|
||||
'': '',
|
||||
'lol': 'lol',
|
||||
|
||||
# Basic text styling.
|
||||
'[u][b]a[/]mdr': '<u><b>a</b>mdr</u>',
|
||||
|
||||
# Links.
|
||||
'[url=https://thomas.touhey.fr/]': '<a href="https://thomas.touhey.fr/">' \
|
||||
'https://thomas.touhey.fr/</a>',
|
||||
}
|
||||
|
||||
# Define the tests wrapper, and define the classes.
|
||||
|
||||
_cnt = 0
|
||||
_len = len(str(len(__test_cases)))
|
||||
_templ = """\
|
||||
def test_htmli{n:0>{l}}(self):
|
||||
import textoutpc as _textoutpc
|
||||
self.assertEqual(_textoutpc.tohtml({i}, inline = True), {r}, \\
|
||||
"for the following text: " + {i})
|
||||
"""
|
||||
|
||||
def _wrap_test(inp, res):
|
||||
global _cnt
|
||||
|
||||
_cnt += 1
|
||||
return _templ.format(n = _cnt, l = _len, i = repr(inp), r = repr(res))
|
||||
|
||||
exec("class _TextoutHTMLiTest(_unittest.TestCase):\n maxDiff = None\n" + \
|
||||
'\n'.join(map(lambda args: _wrap_test(*args), __test_cases.items())),
|
||||
globals())
|
||||
|
||||
# If run as main script, run the test function.
|
||||
|
||||
if __name__ == '__main__':
|
||||
_unittest.main()
|
||||
|
||||
# End of file.
|
47
test/ls.py
47
test/ls.py
|
@ -1,47 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
#******************************************************************************
|
||||
# Copyright (C) 2018 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
||||
# This file is part of the textoutpc project, which is MIT-licensed.
|
||||
#******************************************************************************
|
||||
""" Unit tests for the Python version of textout, lightscript-related funcs.
|
||||
Uses the builtin `unittest` module.
|
||||
"""
|
||||
|
||||
import unittest as _unittest
|
||||
|
||||
__all__ = ["TextoutLSTest"]
|
||||
|
||||
# Define the tests.
|
||||
|
||||
__test_cases = {
|
||||
# Basic text.
|
||||
|
||||
'': '',
|
||||
}
|
||||
|
||||
# Define the tests wrapper, and define the classes.
|
||||
|
||||
_cnt = 0
|
||||
_len = len(str(len(__test_cases)))
|
||||
_templ = """\
|
||||
def test_lgsp{n:0>{l}}(self):
|
||||
import textoutpc as _textoutpc
|
||||
self.assertEqual(_textoutpc.tolightscript({i}), {r}, {i})
|
||||
"""
|
||||
|
||||
def _wrap_test(inp, res):
|
||||
global _cnt
|
||||
|
||||
_cnt += 1
|
||||
return _templ.format(n = _cnt, l = _len, i = repr(inp), r = repr(res))
|
||||
|
||||
exec("class TextoutLSTest(_unittest.TestCase):\n maxDiff = None\n" + \
|
||||
'\n'.join(map(lambda args: _wrap_test(*args), __test_cases.items())),
|
||||
globals())
|
||||
|
||||
# If run as main script, run the test function.
|
||||
|
||||
if __name__ == '__main__':
|
||||
_unittest.main()
|
||||
|
||||
# End of file.
|
|
@ -0,0 +1,230 @@
|
|||
#!/usr/bin/env python3
|
||||
#******************************************************************************
|
||||
# Copyright (C) 2018 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
||||
# This file is part of the textoutpc project, which is MIT-licensed.
|
||||
#******************************************************************************
|
||||
""" Unit tests for the Python version of textout. """
|
||||
|
||||
import pytest
|
||||
|
||||
from textoutpc import tohtml as _tohtml
|
||||
|
||||
# Define the tests.
|
||||
|
||||
@pytest.mark.parametrize('test_input,expected', (
|
||||
# Basic text.
|
||||
|
||||
('', ''),
|
||||
('lol', '<p>lol</p>'),
|
||||
('<script>alert(1);</script>',
|
||||
'<p><script>alert(1);</script></p>'),
|
||||
|
||||
# Other tests. (?)
|
||||
|
||||
('[a][c][/a]', '<p>[a][c][/a]</p>'),
|
||||
('[a][a]', '<p>[a][a]</p>'),
|
||||
("[<>]><[/<>]", "<p>[<>]><[/<>]</p>"),
|
||||
|
||||
# Autolinking.
|
||||
|
||||
('(http://www.example.org/some-[damn-url]-(youknow))',
|
||||
'<p>(<a href="http://www.example.org/some-[damn-url]-(youknow)">' \
|
||||
'http://www.example.org/some-[damn-url]-(youknow)</a>)</p>'),
|
||||
('https://thomas.touhey.fr/, tu vois ?',
|
||||
'<p><a href="https://thomas.touhey.fr/">https://thomas.touhey.fr/' \
|
||||
'</a>, tu vois ?</p>'),
|
||||
|
||||
# Basic text styling.
|
||||
|
||||
('[u][b][a][i][/b]', "<p><u><b>[a]</b></u></p>"),
|
||||
('[u][b]a[/]mdr', '<p><u><b>a</b>mdr</u></p>'),
|
||||
|
||||
# Blocks, alignment.
|
||||
|
||||
('[left]', ''),
|
||||
('[left]lol[/]hi', '<div class="align-left"><p>lol</p></div><p>hi</p>'),
|
||||
('a[justify]b', '<p>a</p><div class="align-justify"><p>b</p></div>'),
|
||||
('a[i]', '<p>a</p>'),
|
||||
('a[i][justify]b', '<p>a</p>' \
|
||||
'<div class="align-justify"><p><i>b</i></p></div>'),
|
||||
('a[i]k[center]b', '<p>a<i>k</i></p>' \
|
||||
'<div class="align-center"><p><i>b</i></p></div>'),
|
||||
('a[i]k[center][b]b[justify]c[/center]d[/]wouhou',
|
||||
'<p>a<i>k</i></p>' \
|
||||
'<div class="align-center"><p><i><b>b</b></i></p>' \
|
||||
'<div class="align-justify"><p><i><b>c</b></i></p></div></div>' \
|
||||
'<p><i>d</i>wouhou</p>'),
|
||||
|
||||
# Show tag for super preprocessing blocks.
|
||||
|
||||
('[show]lol', '<p><span class="inline-code">lol</span></p>'),
|
||||
('[quote][show][justify]hehe',
|
||||
'<div class="citation"><p><span class="inline-code">' \
|
||||
'<div class="align-justify">' \
|
||||
'<p>hehe</p></div>' \
|
||||
'</span></p></div>'),
|
||||
|
||||
# Titles.
|
||||
|
||||
('lolk[title]smth', '<p>lolk</p>' '<h1 class="title">smth</h1>'),
|
||||
('[subtitle]<>', '<h2 class="subtitle"><></h2>'),
|
||||
|
||||
# Fonts.
|
||||
|
||||
('[arial]test', '<p><span style="font-family: arial">test</span></p>'),
|
||||
('[font=mono]stereo',
|
||||
'<p><span style="font-family: monospace">stereo</span></p>'),
|
||||
('[haettenschweiler]', ''),
|
||||
('[font=hello]yea', '<p>[font=hello]yea</p>'),
|
||||
|
||||
# Color.
|
||||
|
||||
('yea[color=blue]dabadee', \
|
||||
'<p>yea<span style="color: #0000FF">dabadee</span></p>'),
|
||||
('[color=#12345F]a', '<p><span style="color: #12345F">a</span></p>'),
|
||||
('[color=#123]a', '<p><span style="color: #112233">a</span></p>'),
|
||||
('[color=123]a', '<p><span style="color: #010203">a</span></p>'),
|
||||
('[color=chucknorris]a', '<p><span style="color: #C00000">a</span></p>'),
|
||||
('[color=rgb(1, 22,242)]a',
|
||||
'<p><span style="color: #0116F2">a</span></p>'),
|
||||
('[color= rgb (1,22, 242 , 50.0% )]a',
|
||||
'<p><span style="color: #0116F2; ' \
|
||||
'color: rgba(1, 22, 242, 0.5)">a</span></p>'),
|
||||
('[color=rgba(1,22,242,0.500)]a', '<p><span style="color: #0116F2; ' \
|
||||
'color: rgba(1, 22, 242, 0.5)">a</span></p>'),
|
||||
('[color=rbga(5, 7)]b', '<p><span style="color: #050007">b</span></p>'),
|
||||
('[color=hsl(0, 1,50.0%)]r',
|
||||
'<p><span style="color: #FF0000">r</span></p>'),
|
||||
# TODO: hls, hwb
|
||||
|
||||
# Links.
|
||||
|
||||
('[url]', '<p>[url]</p>'),
|
||||
('[url=https://thomas.touhey.fr/]mon profil est le meilleur[/url]',
|
||||
'<p><a href="https://thomas.touhey.fr/">mon profil est le meilleur' \
|
||||
'</a></p>'),
|
||||
('[url=https://thomas.touhey.fr/]',
|
||||
'<p><a href="https://thomas.touhey.fr/">https://thomas.touhey.fr/' \
|
||||
'</a></p>'),
|
||||
('[url=http://hey.org/lol[]>"a]', '<p><a href="http://hey.org/lol[]>' \
|
||||
'"a">' 'http://hey.org/lol[]>"a</a></p>'),
|
||||
('[url]javascript:alert(1)[/url]',
|
||||
'<p>[url]javascript:alert(1)[/url]</p>'),
|
||||
('[url]<script>alert(1);</script>[/url]',
|
||||
'<p>[url]<script>alert(1);</script>[/url]</p>'),
|
||||
|
||||
('[profil]cake[/profil]',
|
||||
'<p><a href="https://www.planet-casio.com/Fr/compte/voir_profil.php' \
|
||||
'?membre=cake">cake</a></p>'),
|
||||
('[profile]ekac',
|
||||
'<p><a href="https://www.planet-casio.com/Fr/compte/voir_profil.php' \
|
||||
'?membre=ekac">ekac</a></p>'),
|
||||
|
||||
# Quotes.
|
||||
|
||||
('[quote]', ''),
|
||||
('[quote]a',
|
||||
'<div class="citation"><p>a</p></div>'),
|
||||
('[quote=Test 1 :)]lel[/quote]',
|
||||
'<div class="citation"><p><b>Test 1 ' \
|
||||
'<img src="/images/smileys/smile.gif"> a écrit :</b></p><p>' \
|
||||
'lel</p></div>'),
|
||||
|
||||
# Spoilers.
|
||||
|
||||
('[spoiler]', ''),
|
||||
('[spoiler=Hello|world> :D]Close this, quick![/spoiler]',
|
||||
'<div class="spoiler"><div class="title on" ' \
|
||||
'onclick="toggleSpoiler(this.parentNode, ' "'open'" ');"><p>Hello' \
|
||||
'</p></div><div class="title off" ' \
|
||||
'onclick="toggleSpoiler(this.parentNode, ' "'close'" ');"><p>world' \
|
||||
'> <img src="/images/smileys/grin.gif"></p></div>' \
|
||||
'<div class="off"><p>Close this, quick!</p></div></div>'),
|
||||
|
||||
# Code.
|
||||
|
||||
('[code]', ''),
|
||||
("`[code]`", '<p><span class="inline-code">[code]</span></p>'),
|
||||
|
||||
('[inlinecode]', ''),
|
||||
("[inlinecode]`[/inlinecode]",
|
||||
'<p><span class="inline-code">`</span></p>'),
|
||||
|
||||
("[b]a[noeval]b[/b]c[/noeval]d", "<p><b>ab[/b]cd</b></p>"),
|
||||
("a[noeval]b[noeval]c[/noeval]d[/noeval]e",
|
||||
"<p>ab[noeval]c[/noeval]de</p>"),
|
||||
("[noeval]``[/noeval]", "<p>``</p>"),
|
||||
('[noeval]<>[/noeval]', '<p><></p>'),
|
||||
|
||||
# Pictures.
|
||||
|
||||
('[img]', '<p>[img]</p>'),
|
||||
('[img]"incroyable<>"[/img]',
|
||||
'<p>[img]"incroyable<>"[/img]</p>'),
|
||||
('[img=right|float|12x345]https://example.org/image.png',
|
||||
'<img src="https://example.org/image.png" class="img-float-right" ' \
|
||||
'style="width: 12px; height: 345px" />'),
|
||||
|
||||
# Videos.
|
||||
|
||||
('[video]"><script>alert(1)</script>[/video]',
|
||||
'<p>[video]"><script>alert(1)</script>' \
|
||||
'[/video]</p>'),
|
||||
('[video]<script>alert(document.cookie)</script>[/video]',
|
||||
'<p>[video]<script>alert(document.cookie)</script>' \
|
||||
'[/video]</p>'),
|
||||
('[video]https://www.youtube.com/watch?v=6odDOOyUawY[/video]',
|
||||
'<div class="video-wrapper" style="padding-bottom: 56.25%"><iframe ' \
|
||||
'src="https://www.youtube.com/embed/6odDOOyUawY" ' \
|
||||
'frameborder="0" allowfullscreen></iframe></div>'),
|
||||
('[video]https://www.youtube.com/watch?v=<script>alert(1)</script>',
|
||||
'<p><a href="https://www.youtube.com/watch?v=<script>alert(1)' \
|
||||
'</script>">' \
|
||||
'https://www.youtube.com/watch?v=<script>alert(1)' \
|
||||
'</script></a></p>'),
|
||||
('[video=left|float|4:3]https://www.youtube.com/watch?v=XEjLoHdbVeE',
|
||||
'<div class="video-wrapper img-float-left" ' \
|
||||
'style="padding-bottom: 75%"><iframe ' \
|
||||
'src="https://www.youtube.com/embed/XEjLoHdbVeE" frameborder="0" ' \
|
||||
'allowfullscreen></iframe></div>'),
|
||||
('lol[youtube]h4WLX8hfpJw', '<p>lol</p><div class="video-wrapper" ' \
|
||||
'style="padding-bottom: 56.25%"><iframe ' \
|
||||
'src="https://www.youtube.com/embed/h4WLX8hfpJw" frameborder="0" ' \
|
||||
'allowfullscreen></iframe></div>'),
|
||||
|
||||
('[color=blue][youtube]h4WLX8hfpJw',
|
||||
'<div class="video-wrapper" style="padding-bottom: 56.25%">' \
|
||||
'<iframe src="https://www.youtube.com/embed/h4WLX8hfpJw" ' \
|
||||
'frameborder="0" allowfullscreen></iframe></div>'),
|
||||
('[color=blue]oh[youtube]h4WLX8hfpJw',
|
||||
'<p><span style="color: #0000FF">oh</span></p>' \
|
||||
'<div class="video-wrapper" style="padding-bottom: 56.25%"><iframe ' \
|
||||
'src="https://www.youtube.com/embed/h4WLX8hfpJw" frameborder="0" ' \
|
||||
'allowfullscreen></iframe></div>'),
|
||||
|
||||
# Progress bars.
|
||||
|
||||
('[progress=lol]mdr[/progress]', '<p>[progress=lol]mdr[/progress]</p>'),
|
||||
|
||||
# Text rotation obfuscation.
|
||||
|
||||
('[rot13]obawbhe[/rot13]', '<p>bonjour</p>'),
|
||||
|
||||
# Lists.
|
||||
|
||||
('[list]haha[b][*]wow[*]incredible[/b][/*]wow[*]yuy[/list]',
|
||||
'<ul><li><p>wow</p></li><li><p>incredible[/b]</p></li>' \
|
||||
'<li><p>yuy</p></li></ul>'),
|
||||
('[list]\n[*]bonjour', '<ul><li><p>bonjour</p></li></ul>'),
|
||||
|
||||
# Smileys.
|
||||
|
||||
(':)', '<p><img src="/images/smileys/smile.gif"></p>'),
|
||||
(':):)', '<p>:):)</p>'),
|
||||
(':) :D', '<p><img src="/images/smileys/smile.gif"> ' \
|
||||
'<img src="/images/smileys/grin.gif"></p>'),
|
||||
))
|
||||
def test_html(test_input, expected):
|
||||
assert _tohtml(test_input) == expected
|
||||
|
||||
# End of file.
|
|
@ -0,0 +1,30 @@
|
|||
#!/usr/bin/env python3
|
||||
#******************************************************************************
|
||||
# Copyright (C) 2018 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
||||
# This file is part of the textoutpc project, which is MIT-licensed.
|
||||
#******************************************************************************
|
||||
""" Unit tests for the Python version of textout. """
|
||||
|
||||
import pytest
|
||||
|
||||
from textoutpc import tohtml as _tohtml
|
||||
|
||||
@pytest.mark.parametrize('test_input,expected', (
|
||||
# Basic text.
|
||||
|
||||
('', ''),
|
||||
('lol', 'lol'),
|
||||
|
||||
# Basic text styling.
|
||||
|
||||
('[u][b]a[/]mdr', '<u><b>a</b>mdr</u>'),
|
||||
|
||||
# Links.
|
||||
|
||||
('[url=https://thomas.touhey.fr/]',
|
||||
'<a href="https://thomas.touhey.fr/">https://thomas.touhey.fr/</a>'),
|
||||
))
|
||||
def test_htmli(test_input, expected):
|
||||
assert _tohtml(test_input, inline = True) == expected
|
||||
|
||||
# End of file.
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env python3
|
||||
#******************************************************************************
|
||||
# Copyright (C) 2018 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
||||
# This file is part of the textoutpc project, which is MIT-licensed.
|
||||
#******************************************************************************
|
||||
""" Unit tests for the Python version of textout, lightscript-related
|
||||
functions. """
|
||||
|
||||
import pytest
|
||||
|
||||
from textoutpc import tolightscript as _tolightscript
|
||||
|
||||
@pytest.mark.parametrize('test_input,expected', (
|
||||
# Basic text.
|
||||
|
||||
('', ''),
|
||||
))
|
||||
def test_lightscript(test_input, expected):
|
||||
assert _tolightscript(test_input) == expected
|
||||
|
||||
# End of file.
|
|
@ -101,7 +101,7 @@ class TextoutStream:
|
|||
#
|
||||
# FIXME: check the sizes? it seems that it stopped working…
|
||||
|
||||
_Tag = _re.compile("""\
|
||||
_Tag = _re.compile(r"""
|
||||
\[\s?
|
||||
(?P<bname>
|
||||
(?P<bname_e>[^\/\[\]\=][^\[\]\=]* (\[(?&bname_e)\]?)*)*
|
||||
|
|
Loading…
Reference in New Issue