2
0
Fork 0

Changed way raw is identified, corrected leftover bugs

This commit is contained in:
Thomas Touhey 2018-01-24 12:33:33 +01:00
parent a5445e78f8
commit 20f9e61e72
No known key found for this signature in database
GPG Key ID: 2ECEB0517AD947FB
17 changed files with 187 additions and 116 deletions

141
GUIDE.md
View File

@ -6,6 +6,11 @@ The BBcode markup language mainly uses tags, which the starting mark looks
like `[xxx]` and the ending mark looks like `[/xxx]`. You can add an attribute
to the starting mark to modify the tag's behaviour.
There is a generic/quick ending mark which looks like `[/]`.
It cannot be used with all tags, so when it is used in the examples below,
suppose you can use it, otherwise, it might not be possible (or not
implemented yet).
## Align the text
To align the text, you can use either `[<alignment mode>]` or
`[align=<alignment mode>]` with any of the following modes:
@ -18,7 +23,16 @@ To align the text, you can use either `[<alignment mode>]` or
For example, to right-align some text, you could do something like this:
[right]some text[/right]
[right]some text[/]
## Inserting titles
Do you want to include titles or subtitles to your message, integrated with
the website's design? Use the `[title]` and `[subtitle]` tags for that:
[title]Just do it![/title]
[subtitle]Don't let your dreams be dreams![/subtitle]
Notice that this tag cannot embed another tag.
## Styling the text
You can add some basic text style by using the following tags:
@ -28,6 +42,8 @@ You can add some basic text style by using the following tags:
- `[u]` for underlined text;
- `[s]` or `[striked]` for ~striked~ text.
They can all be ended with the generic ending mark `[/]`.
## Changing the text font
You can change the font of the text by using the `[font=xxx]` (or `[xxx]`
directly, where `xxx` represents the font identifier) tag. The following
@ -40,6 +56,8 @@ fonts are available:
- `haettenschweiler` represents Haettenschweiler;
- `mono` and `monospace` represents the basic monospace font.
They can be ended with the generic ending mark `[/]` as well.
## Changing the text color
You can change the color of the text using the `[color=xxx]` (or `[xxx]`
directly for simple colors, where `xxx` represents the color) tag. This
@ -73,6 +91,60 @@ Here are some examples:
[color=rgb(255, 255,255,0.4)]I'm black![/]
[color=hsl(0,100%, 0.5)]I'm red![/]
## Inserting hyperlinks
Creating hyperlinks on a bunch of text is possible through the `[url]` tag.
The URL has to be either absolute, relative, or related to an anchor. It has
to be passed to the tag either through the argument (which allows the content
to be the displayed title of the link) or through the content if there is
no argument. By default, if there is no content and an argument, the argument
will be taken as the link title.
Here are examples:
[url]https://planet-casio.com[/url]
[url=https://planet-casio.com]Planète Casio[/url]
[url=/relative/url.html][/url]
To link to profiles, the `[profil]` and `[profile]` tags can be used. They
take no attribute but take a content which is the user whose the profile
is to be linked's name. For example:
[profil]Cakeisalie5[/profil]
## Quoting someone
To quote someone visually, you can use the `[quote]` tag, which takes the
name of the person you're quoting as the attribute and the quote as the
content. A quote can contain another one, of course. If there is no name,
the display will just be generalistic.
Here are examples:
[quote]Someone said that.[/]
[quote=Cakeisalie5]Ever realized that my name contained “Cake”?[/]
## Spoilers/Content Warnings
To hide something behind a deliberate action of your user, usually to avoid
hurting people or to hide the solution to a problem, you can use the
`[spoiler]` tag.
[spoiler]This is hidden![/]
[spoiler=Uncover the dark secrets of the night]Boo![/]
[spoiler=Uncover this!|Cover this quick!!]BOOO![/]
## Presenting code
There are two code tags:
- `[code]`, which is supposed to be used as a block for multiline code or
to isolate the code from the text;
- `[inlinecode]` or the _backquotes_ to include code in the text.
For example:
[code]Some multiline code, with [center]tags shown as they are[/center].
Incredible, heh?[/code]
[inlinecode]Some inline code.[/inlinecode]
`Some more inline code.`
## Inserting an image
In order to insert an image, you will have to use the `[img]` tag. It will
make a new paragraph containing the image which the URL is given in the
@ -86,48 +158,51 @@ the pipe (`|`) character:
- `left`, `right`, `center`: align the image accordingly;
- `float`: make the image float, i.e. let the text be where the image isn't.
For example, `[img=right|float|x24]https://example.org/image.jpg[/img]`
For example:
[img=right|float|x24]https://example.org/image.jpg[/img]
is a right-aligned image, floating (which means text will be allowed on
the left of the image), and with a height of 24 pixels and an automatic
width.
Planète Casio admins can use the `[adimg]` tag which is equivalent to the
`[img]` tag but adds the special admin image folder prefix to the image
URLs, so `[adimg]incredible.jpg[/adimg]` is possible.
URLs, so this is possible:
## Inserting hyperlinks
Creating hyperlinks on a bunch of text is possible through the `[url]` tag.
[adimg]incredible.jpg[/adimg]
## Other tags (TODO)
Some day, I will write a complete guide, but as a quickstart, here are the
different tags you can use:
## Inserting a video
This BBcode translator has the ability to integrate videos from some online
platforms into your message, as a block. To do this, you can use the
`[video]` and `[video tiny]` tags. For example:
[code]Some multiline
code[/code]
[inlinecode]Some inline code[/inlinecode] / `Some inline code`
[noeval][center]Code notevaluated[/center][/noeval]
[url]https://planet-casio.com[/url]
[url=https://planet-casio.com]Planète Casio[/url]
[url=/relative/url.php][/url]
[profil]Cakeisalie5[/profil]
[title]Just do it![/title]
[subtitle]Don't let your dreams be dreams![/subtitle]
[progress=50]Building a great wall…[/progress]
[progress=100][/progress]
[quote]Someone said that.[/quote]
[quote=Cakeisalie5]Ever realized that my name contained “Cake”?[/quote]
[spoiler]This is hidden![/quote]
[quote=Uncover the dark secrets of the night]Boo![/quote]
[quote=Uncover this!|Cover this quick!!]BOOO![/quote]
[video]https://www.youtube.com/watch?v=yhXpV8hRKxQ[/video]
[video tiny]https://www.youtube.com/watch?v=yhXpV8hRKxQ[/video tiny]
## Inserting a progress bar
Do you want to present how your project is evolving using a simple graph,
the progress bar? This is possible using the `[progress]` tag, which takes
the percentage (between 0 and 100 included) of the advancement as its
attribute. For example:
[progress=50]Building a great wall…[/progress]
[progress=100][/progress]
## Inserting labels and targets
Is your message in several parts and you only want to link one without using
an entire separate page for the section? This is the tag you might want
to use. To link to a point in your message:
- first, define the label using the `[label]` tag, with the name of the label
as the attribute;
- then link to the label using the `[target]` tag.
You are not obliged to terminate the `[label]` tag (the original version of
it didn't support the `[label]` tag termination, in fact). For example:
[label=sometag][subtitle]Some chapter[/subtitle]
[rot13]obawbhe[/rot13]
[small]one day, i will go to the moon![/small] — [big]why wait?[/big]
...
[label=sometag]
[target=sometag]Go check out that section![/target]
[strike]Usage of the quick tag ending[/]
[target=sometag]Go back to the beginning of the chapter[/target]

33
TAGS.md
View File

@ -6,27 +6,24 @@ that starts with `Textout` and an uppercase character, and finishes by
`Tag`, and shall inherit one of the base classes defined in
`textoutpc.Tags.__base__` depending on how the tag will be used:
- `TextoutInlineBlockTag`: tag to be used inside a paragraph, e.g. text
formatting;
- `TextoutInlineTag`: same as previous, is ignored if without content;
- `TextoutBlockTag`: tag to be used at paragraph level, e.g. video;
- `TextoutParagraphTag`: same as previous, is ignored if without content
(this base class also serves as the generic paragraph tag);
- `TextoutRawTag`: do not transform the content of this tag before giving
it to the tag (if required, see below), e.g. code blocks.
- `TextoutInlineTag`: tag to be used inside a paragraph,
e.g. text formatting;
- `TextoutBlockTag`: tag to be used at paragraph level, e.g. video.
If your tag shall be used as several of the previous base classes, please
prefer the use of the fusioned classes: `TextoutRawInlineBlockTag`,
`TextoutRawInlineTag`, `TextoutRawBlockTag`, `TextoutRawParagraphTag`.
There are a few public members you can define as a tag:
The first public member must be `aliases`, and be defined as an array to
the names this tag can be accessed as. Basic tags (the ones with
brackets `[]`) are defined as `[<name>]` (e.g. `[hello]`) and special
characters are defined with their symbol, e.g. `\``. So for example, if I
want to make the inline tag `[hello]` as an example, with the alternate
name `[hai]`, I'd start off by writing:
- `aliases`: the array of names this tag can be accessed as.
Basic tags (the ones with brackets `[]`) are defined as `[<name>]`
(e.g. `[hello]`) and special characters are defined with their symbol,
e.g. `\``;
- `raw`: the tag's content shall not be interpreted, which is generally
only useful when the content is preprocessed (see below). The default
is `False` if there is no preprocess method, and `True` otherwise.
from .__base__ import TextoutInlineTag
So for example, if I want to make the inline tag `[hello]` as an example,
with the alternate name `[hai]`, I'd start off by writing:
from .__base__ import *
class TextoutHelloTag(TextoutInlineTag):
""" The [hello] tag, which does things.

View File

@ -5,7 +5,7 @@ from .__base__ import *
__all__ = ["TextoutCodeTag", "TextoutInlineCodeTag", "TextoutNoEvalTag"]
class TextoutCodeTag(TextoutRawBlockTag):
class TextoutCodeTag(TextoutBlockTag):
""" The basic code tag, for displaying code.
Example uses:
@ -15,6 +15,7 @@ class TextoutCodeTag(TextoutRawBlockTag):
}[/code] """
aliases = ('[code]',)
raw = True
def begin_text(self):
return "```\n"
@ -28,7 +29,7 @@ class TextoutCodeTag(TextoutRawBlockTag):
def end_html(self):
return '</div>'
class TextoutInlineCodeTag(TextoutRawInlineTag):
class TextoutInlineCodeTag(TextoutInlineTag):
""" Inline code tag, doesn't display a box, simply doesn't evaluate
the content and uses monospace font.
Example uses:
@ -39,6 +40,7 @@ class TextoutInlineCodeTag(TextoutRawInlineTag):
"""
aliases = ('`', '[inlinecode]')
raw = True
def begin_text(self):
return "`"
@ -52,7 +54,7 @@ class TextoutInlineCodeTag(TextoutRawInlineTag):
def end_html(self):
return '</span>'
class TextoutNoEvalTag(TextoutRawInlineTag):
class TextoutNoEvalTag(TextoutInlineTag):
""" Inline code tag, simply doesn't evaluate the content.
Example uses:
@ -60,5 +62,6 @@ class TextoutNoEvalTag(TextoutRawInlineTag):
"""
aliases = ('[noeval]',)
raw = True
# End of file.

View File

@ -7,7 +7,7 @@ from .__base__ import *
__all__ = ["TextoutImageTag", "TextoutAdminImageTag"]
class TextoutImageTag(TextoutRawBlockTag):
class TextoutImageTag(TextoutBlockTag):
""" The main tag for displaying an image.
Example uses:
@ -19,6 +19,7 @@ class TextoutImageTag(TextoutRawBlockTag):
"""
aliases = ('[img]',)
raw = True
def prepare(self, name, value):
self._width = None

View File

@ -52,7 +52,7 @@ class TextoutTargetTag(TextoutInlineTag):
return ' (voir "{}")'.format(self._label)
def begin_html(self):
#name = 'label-' + self.value
#name = 'label-' + self._label
name = self._label if _v42compat else 'label-' + self._label
return '<a href="#{}">'.format(name)

View File

@ -6,7 +6,7 @@ from html import escape as _htmlescape
__all__ = ["TextoutLinkTag", "TextoutProfileTag"]
class TextoutLinkTag(TextoutRawInlineTag):
class TextoutLinkTag(TextoutInlineTag):
""" The main link tag.
Example uses:
@ -16,6 +16,7 @@ class TextoutLinkTag(TextoutRawInlineTag):
"""
aliases = ('[url]',)
raw = True
def _validate(self):
for prefix in ('http://', 'https://', 'ftp://', '/', '#'):

View File

@ -5,7 +5,7 @@ from .__base__ import *
__all__ = ["TextoutProgressTag"]
class TextoutProgressTag(TextoutRawBlockTag):
class TextoutProgressTag(TextoutBlockTag):
""" Progress tag, used to display the progress on anything.
Usage:
@ -13,6 +13,7 @@ class TextoutProgressTag(TextoutRawBlockTag):
[progress=100][/progress] """
aliases = ('[progress]',)
raw = True
def prepare(self, name, value):
self._val = int(value)

View File

@ -32,7 +32,7 @@ class TextoutQuoteTag(TextoutBlockTag):
return '{} a écrit:\n'.format(self._value)
def content_text(self):
return "> " + '\n> '.join(self.content.split('\n'))
return "> " + '\n> '.join(self._content.split('\n'))
def begin_html(self):
f = '<div class="citation">'

View File

@ -7,7 +7,7 @@ from html import escape as _htmlescape
__all__ = ["TextoutRotTag"]
class TextoutRotTag(TextoutRawInlineTag):
class TextoutRotTag(TextoutInlineTag):
""" Tag which un-rot13 a content.
Demonstration tag for content processing.
Example uses:
@ -17,6 +17,7 @@ class TextoutRotTag(TextoutRawInlineTag):
"""
aliases = ('[rot]', '[rot13]')
raw = True
def prepare(self, name, value):
if name == "[rot]":

View File

@ -14,6 +14,7 @@ class TextoutShowTag(TextoutBlockTag):
"""
aliases = ('[show]',)
raw = False
def preprocess_html(self, content):
return _htmlescape(content)

View File

@ -5,7 +5,7 @@ from .__base__ import *
__all__ = ["TextoutTitleTag"]
class TextoutTitleTag(TextoutRawBlockTag):
class TextoutTitleTag(TextoutBlockTag):
""" The title tag.
Example uses:
@ -14,6 +14,7 @@ class TextoutTitleTag(TextoutRawBlockTag):
"""
aliases = ('[title]', '[subtitle]')
raw = True
def prepare(self, name, value):
self._level = name[1:-1]

View File

@ -13,7 +13,7 @@ _hexcode = _re.compile('[a-zA-Z0-9_]+')
_numcode = _re.compile('^/[0-9]+$')
_dailypath = _re.compile('^/video/([a-z0-9]+)$')
class TextoutVideoTag(TextoutRawBlockTag):
class TextoutVideoTag(TextoutBlockTag):
""" The video tag, puts a preview of the video whose URL is given.
Only a few 'big' services are supported for now.
Example uses:
@ -24,11 +24,12 @@ class TextoutVideoTag(TextoutRawBlockTag):
"""
aliases = ('[video]', '[video tiny]')
raw = True
def prepare(self, name, value):
""" Prepare the video tag. """
self._sizeclass = "video-tiny" if "tiny" in self.name \
self._sizeclass = "video-tiny" if "tiny" in name \
else "video-medium"
self._center = False

View File

@ -3,9 +3,7 @@
from functools import partial as _p
__all__ = ["TextoutRawTag",
"TextoutBlockTag", "TextoutRawBlockTag",
"TextoutInlineTag", "TextoutRawInlineTag"]
__all__ = ["TextoutBlockTag", "TextoutInlineTag"]
# ---
# Main base tag class.
@ -22,26 +20,12 @@ class TextoutTag:
aliases = ()
@property
def name(self):
return self.__name
@property
def _full(self):
return self.__full
def __init__(self, name, value, ot):
""" Initialize the textout tag with the documented members. """
# Store internal data.
self.__output_type = ot
self.__name = name
if name[0] + name[-1] == "[]":
self.__full = "[" + name[1:-1] + ("=" + value if value != None \
else "") + "]"
else:
self.__full = name
# Call both prepare functions.
@ -104,17 +88,9 @@ class TextoutTag:
# Role-specific base tag classes.
# ---
class TextoutRawTag:
pass
class TextoutBlockTag(TextoutTag):
pass
class TextoutRawBlockTag(TextoutBlockTag, TextoutRawTag):
pass
class TextoutInlineTag(TextoutTag):
pass
class TextoutRawInlineTag(TextoutInlineTag, TextoutRawTag):
pass
# End of file.

View File

@ -1,5 +1,8 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
""" HTML/CSS like color parsing, mainly for the `[color]` tag.
Defines the `get_color()` function which returns an rgba value.
"""
import re as _re
import colorsys as _color
@ -74,7 +77,7 @@ _colors = {
'transparent': 'rgba(0, 0, 0, 0)',
}
_cr = _re.compile('^\s*('
_cr = _re.compile(''
'rgba?\s*\('
'\s*' '(?P<rgb_r>[0-9]{1,3})' '\s*,'
'\s*' '(?P<rgb_g>[0-9]{1,3})' '\s*,'
@ -110,9 +113,9 @@ _cr = _re.compile('^\s*('
# '\s*' '((?P<hwb_blk_per>0*[0-9]{1,3})%'
# '|(?P<hwb_blk_flt>0*(\.[0-9]*)?))' '\s*'
# '\)'
'|\#?'
'|(?P<hex_hash>\#?)'
'(?P<hex_digits>[0-9a-z]*)'
')\s*$', _re.I)
'', _re.I)
# ---
# Utilitaires.
@ -151,7 +154,7 @@ def get_color(value):
hx = match['hex_digits'].lower()
hx = ''.join(c if c in '0123456789abcdef' \
else ('0', '00')[ord(c) > 0xFFFF] for c in hx)[:128]
if len(hx) == 3:
if match['hex_hash'] and len(hx) == 3:
hx = hx[0] * 2 + hx[1] * 2 + hx[2] * 2
iv = _math.ceil(len(hx) / 3)
@ -173,8 +176,6 @@ def get_color(value):
alpha = float(match['rgb_a_per']) / 100.0
elif match['rgb_a_flt']:
alpha = float(match['rgb_a_flt'])
else:
alpha = 1.0
elif match['hsl_hue'] or match['hls_hue']:
if match['hsl_hue']:
hue = float(match['hsl_hue'])
@ -201,8 +202,6 @@ def get_color(value):
alpha = float(match['hsl_aph_per']) / 100.0
elif match['hsl_aph_flt']:
alpha = float(match['hsl_aph_flt'])
else:
alpha = 1.0
else:
hue = float(match['hls_hue'])
agl = match['hls_agl']
@ -224,8 +223,6 @@ def get_color(value):
alpha = float(match['hls_aph_per']) / 100.0
elif match['hls_aph_flt']:
alpha = float(match['hls_aph_flt'])
else:
alpha = 1.0
# Prepare the angle.
if agl == 'grad':

View File

@ -1,8 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from .__base__ import TextoutTag, TextoutRawTag, \
TextoutInlineTag, TextoutBlockTag
from .__base__ import *
from .Align import *
from .Code import *

View File

@ -98,16 +98,16 @@ class TextoutStream:
# FIXME: check the sizes? it seems that it stopped working…
_Tag = _re.compile("""\
\[(?P<bname>
\[\s?(?P<bname>
(?P<bname_e>[^\/\[\]\=][^\[\]\=]* (\[(?&bname_e)\]?)*)*
)
(=(?P<value>
(\s?=\s?(?P<value>
(?P<value_e>[^\[\]]* (\[(?&value_e)\]?)*)*
))?\]
))?\s?\]
|
\[[\\/](?P<ename>
\[[\\/]\s?(?P<ename>
(?P<ename_e>[^\/\[\]\=][^\[\]\=]* (\[(?&ename_e)\]?)*)*
)\]
)\s?\]
|
(?P<parsep>[\n]{2,})
|

View File

@ -6,13 +6,26 @@
import regex as _re
from html import escape as _htmlescape
from .Tags import TextoutRawTag, TextoutInlineTag, TextoutBlockTag, get_tag
from .Tags import TextoutInlineTag, TextoutBlockTag, get_tag
from .stream import *
from .smileys import htmlsmileys as _htmlsmileys
from .urls import htmlurls as _htmlurls
__all__ = ["Translator"]
# ---
# Tag data utility.
# ---
class _TagData:
def __init__(self, tag, name, attr, full):
self.name = name
self.attr = attr
self.full = full
self.tag = tag
self.raw = bool(tag.raw) if hasattr(tag, 'raw') \
else hasattr(tag, 'preprocess')
# ---
# Translator main class.
# ---
@ -212,9 +225,11 @@ class Translator:
# TODO: other things
def push_tag(self, tag):
def push_tag(self, dat):
""" Push a tag onto the tag stack. """
tag = dat.tag
# If the tag processes the content before its usage, we want the
# translator to keep the content up until the end of the tag to
# be able to send it afterwards to the tag.
@ -244,8 +259,8 @@ class Translator:
# Don't forget to add the tag to the queue, and to enable raw
# mode if the tag expects a raw content (e.g. `[code]`).
self.queue.insert(0, tag)
if isinstance(tag, TextoutRawTag):
self.queue.insert(0, dat)
if dat.raw:
self.raw_mode = True
self.raw_deg = 0
@ -264,7 +279,8 @@ class Translator:
# Pop the tag out of the queue.
tag = self.queue.pop(0)
dat = self.queue.pop(0)
tag = dat.tag
# If preprocessing has been enabled, we ought to process the content,
# check if the tag is valid, and do everything we would have done
@ -290,7 +306,7 @@ class Translator:
# The tag is invalid in the end, so we ought to send the
# raw things to the text group and forget about the tag.
self.put_text(tag._full)
self.put_text(dat.full)
self.put_text(content)
self.put_text(end)
return
@ -308,7 +324,7 @@ class Translator:
self.put_code(tag.begin())
if hasattr(tag, 'content'):
self.put_code(tag.content())
elif not isinstance(tag, TextoutRawTag):
elif not dat.raw:
self.put_code(content)
else:
self.put_text(content)
@ -337,7 +353,7 @@ class Translator:
# Disable raw mode if it was a raw tag (which means that it enabled it,
# as tags into raw tags cannot be processed).
if isinstance(tag, TextoutRawTag):
if dat.raw:
self.raw_mode = False
def process(self):
@ -400,8 +416,8 @@ class Translator:
pos = 0
else:
# Get the position corresponding to the tag.
for qpos, qtag in enumerate(self.queue):
if tagdata.name == qtag.name:
for qpos, qdat in enumerate(self.queue):
if tagdata.name == qdat.name:
pos = qpos
break
@ -448,7 +464,8 @@ class Translator:
# And don't forget to push the tag.
self.push_tag(tag)
dat = _TagData(tag, tagdata.name, tagdata.value, tagdata.full)
self.push_tag(dat)
# End of file, it seems! Let's close the tags, flush the text
# and just resume our lives from there.