Compare commits
No commits in common. "bc20e47fb1a39426e18fad18077a8a1aff368914" and "51a163bd73647595f0b335bccaff04f795d250ea" have entirely different histories.
bc20e47fb1
...
51a163bd73
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,7 +2,6 @@ __pycache__
|
|||||||
.mypy_cache
|
.mypy_cache
|
||||||
*.egg-info
|
*.egg-info
|
||||||
*.pyc
|
*.pyc
|
||||||
venv
|
|
||||||
|
|
||||||
*.qmlc
|
*.qmlc
|
||||||
*.jsc
|
*.jsc
|
||||||
|
@ -17,7 +17,6 @@ but compiling on Windows and macOS should be possible with the right tools.
|
|||||||
- [Gentoo / emerge](#gentoo-emerge)
|
- [Gentoo / emerge](#gentoo-emerge)
|
||||||
- [Ubuntu 19.04 / apt](#ubuntu-1904-apt)
|
- [Ubuntu 19.04 / apt](#ubuntu-1904-apt)
|
||||||
- [Ubuntu 19.10+, Debian bullseye / apt](#ubuntu-1910-debian-bullseye-apt)
|
- [Ubuntu 19.10+, Debian bullseye / apt](#ubuntu-1910-debian-bullseye-apt)
|
||||||
- [Pop! OS](#pop-os)
|
|
||||||
- [Void Linux / xbps](#void-linux-xbps)
|
- [Void Linux / xbps](#void-linux-xbps)
|
||||||
- [Installing PyOtherSide manually](#installing-pyotherside-manually)
|
- [Installing PyOtherSide manually](#installing-pyotherside-manually)
|
||||||
- [Installing libolm manually](#installing-libolm-manually)
|
- [Installing libolm manually](#installing-libolm-manually)
|
||||||
@ -167,7 +166,7 @@ export PATH="/usr/lib/qt5/bin:$PATH"
|
|||||||
#### Arch Linux / pacman
|
#### Arch Linux / pacman
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
pacman -S qt5-base qt5-declarative qt5-quickcontrols2 qt5-svg \
|
pacman -Syu qt5-base qt5-declarative qt5-quickcontrols2 qt5-svg \
|
||||||
qt5-graphicaleffects qt5-imageformats \
|
qt5-graphicaleffects qt5-imageformats \
|
||||||
libx11 libxss alsa-lib \
|
libx11 libxss alsa-lib \
|
||||||
python python-pip \
|
python python-pip \
|
||||||
@ -257,35 +256,17 @@ sudo apt install qt5-default qt5-qmake qt5-image-formats-plugins \
|
|||||||
libolm-dev
|
libolm-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Pop! OS
|
|
||||||
|
|
||||||
No need to install libolm manually.
|
|
||||||
|
|
||||||
```sh
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install qt5-qmake qt5-image-formats-plugins qml-module-qtquick2 \
|
|
||||||
qml-module-qtquick-window2 qml-module-qtquick-layouts \
|
|
||||||
qml-module-qtquick-dialogs qml-module-qt-labs-platform \
|
|
||||||
qml-module-qtquick-shapes qml-module-qt-labs-qmlmodels \
|
|
||||||
qml-module-qtgraphicaleffects qml-module-qtquick-controls2 \
|
|
||||||
qtdeclarative5-dev qtquickcontrols2-5-dev libx11-dev \
|
|
||||||
libxss-dev libasound2-dev python3-dev python3-pip \
|
|
||||||
qml-module-io-thp-pyotherside build-essential git \
|
|
||||||
cmake zlib1g-dev libtiff5-dev libwebp-dev libopenjp2-7-dev \
|
|
||||||
libmediainfo-dev libolm-dev meson libdbus-glib-1-dev \
|
|
||||||
libgirepository1.0-dev patchelf
|
|
||||||
pip3 install --user dbus-python
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Void Linux / xbps
|
#### Void Linux / xbps
|
||||||
|
|
||||||
|
[PyOtherSide](#installing-pyotherside-manually) must be manually installed.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo xbps-install -Su qt5-devel qt5-declarative-devel \
|
sudo xbps-install -Su qt5-devel qt5-declarative-devel \
|
||||||
qt5-quickcontrols2-devel \
|
qt5-quickcontrols2-devel \
|
||||||
qt5-svg-devel qt5-graphicaleffects qt5-imageformats \
|
qt5-svg-devel qt5-graphicaleffects qt5-imageformats \
|
||||||
libx11-devel libXScrnSaver-devel alsa-lib-devel \
|
libx11-devel libXScrnSaver-devel alsa-lib-devel \
|
||||||
python3-devel python3-pip \
|
python3-devel python3-pip \
|
||||||
olm-devel pyotherside \
|
olm-devel \
|
||||||
base-devel git cmake \
|
base-devel git cmake \
|
||||||
libjpeg-turbo-devel zlib-devel tiff-devel libwebp-devel \
|
libjpeg-turbo-devel zlib-devel tiff-devel libwebp-devel \
|
||||||
libopenjpeg2-devel libmediainfo-devel
|
libopenjpeg2-devel libmediainfo-devel
|
||||||
|
@ -49,4 +49,4 @@ We suggest setting memorable keybindings. In the above example,
|
|||||||
<kbd>Ctrl+G Ctrl+M</kbd> could mean "Go to Moment". Note that key chords in
|
<kbd>Ctrl+G Ctrl+M</kbd> could mean "Go to Moment". Note that key chords in
|
||||||
Moment can be as long as you want - for example, you could have
|
Moment can be as long as you want - for example, you could have
|
||||||
<kbd>Ctrl+G Ctrl+M Ctrl+O</kbd> for `#moment-client:matrix.org` and
|
<kbd>Ctrl+G Ctrl+M Ctrl+O</kbd> for `#moment-client:matrix.org` and
|
||||||
<kbd>Ctrl+G Ctrl+M Ctrl+A</kbd> for `#matrix:matrix.org`.
|
<kbd>Ctrl+G Ctrl+M Ctrl+I</kbd> for `#mirage-client:matrix.org`.
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
Pillow >= 7.0.0, < 9
|
Pillow >= 7.0.0, < 9
|
||||||
aiofiles >= 0.4.0, < 24.0.0
|
aiofiles >= 0.4.0, < 0.7
|
||||||
appdirs >= 1.4.4, < 2
|
appdirs >= 1.4.4, < 2
|
||||||
cairosvg >= 2.4.2, < 3
|
cairosvg >= 2.4.2, < 3
|
||||||
filetype >= 1.0.7, < 2
|
filetype >= 1.0.7, < 2
|
||||||
html_sanitizer >= 1.9.1, < 2
|
html_sanitizer >= 1.9.1, < 2
|
||||||
lxml >= 4.5.1, < 5
|
lxml >= 4.5.1, < 5
|
||||||
mistune >= 2.0.0, < 3.0
|
mistune >= 0.8.4, < 0.9
|
||||||
pymediainfo >= 4.2.1, < 5
|
pymediainfo >= 4.2.1, < 5
|
||||||
plyer >= 1.4.3, < 2
|
plyer >= 1.4.3, < 2
|
||||||
sortedcontainers >= 2.2.2, < 3
|
sortedcontainers >= 2.2.2, < 3
|
||||||
@ -14,8 +14,9 @@ redbaron >= 0.9.2, < 1
|
|||||||
hsluv >= 5.0.0, < 6
|
hsluv >= 5.0.0, < 6
|
||||||
simpleaudio >= 1.0.4, < 2
|
simpleaudio >= 1.0.4, < 2
|
||||||
dbus-python >= 1.2.16, < 2; platform_system == "Linux"
|
dbus-python >= 1.2.16, < 2; platform_system == "Linux"
|
||||||
matrix-nio[e2e] >= 0.20.1, < 1.0.0
|
|
||||||
|
|
||||||
async_generator >= 1.10, < 2; python_version < "3.7"
|
async_generator >= 1.10, < 2; python_version < "3.7"
|
||||||
dataclasses >= 0.6, < 0.7; python_version < "3.7"
|
dataclasses >= 0.6, < 0.7; python_version < "3.7"
|
||||||
pyfastcopy >= 1.0.3, < 2; python_version < "3.8"
|
pyfastcopy >= 1.0.3, < 2; python_version < "3.8"
|
||||||
|
|
||||||
|
git+https://github.com/MRAAGH/matrix-nio#egg=matrix-nio[e2e]
|
||||||
|
@ -41,11 +41,8 @@ from .user_files import (
|
|||||||
|
|
||||||
# Logging configuration
|
# Logging configuration
|
||||||
log.getLogger().setLevel(log.INFO)
|
log.getLogger().setLevel(log.INFO)
|
||||||
if hasattr(nio, 'log'):
|
nio.logger_group.level = nio.log.logbook.WARNING
|
||||||
nio.logger_group.level = nio.log.logbook.WARNING
|
nio.log.logbook.StreamHandler(sys.stderr).push_application()
|
||||||
nio.log.logbook.StreamHandler(sys.stderr).push_application()
|
|
||||||
else:
|
|
||||||
log.getLogger('nio').setLevel(log.WARNING)
|
|
||||||
|
|
||||||
|
|
||||||
class Backend:
|
class Backend:
|
||||||
|
@ -18,32 +18,84 @@ from lxml.html import HtmlElement, etree # nosec
|
|||||||
from .color import SVGColor
|
from .color import SVGColor
|
||||||
|
|
||||||
|
|
||||||
def parse_colour(inline, m, state):
|
class MarkdownInlineGrammar(mistune.InlineGrammar):
|
||||||
colour = m.group(1)
|
"""Markdown inline elements syntax modifications for the Mistune parser.
|
||||||
text = m.group(2)
|
|
||||||
return "colour", colour, text
|
|
||||||
|
|
||||||
|
- Disable underscores for bold/italics (e.g. `__bold__`)
|
||||||
|
|
||||||
def render_html_colour(colour, text):
|
- Add syntax for coloring text: `<color>(text)`,
|
||||||
return f'<span data-mx-color="{colour}">{text}</span>'
|
e.g. `<red>(Lorem ipsum)` or `<#000040>(sit dolor amet...)`
|
||||||
|
"""
|
||||||
|
|
||||||
|
escape = re.compile(r"^\\([\\`*{}\[\]()#+\-.!_<>~|])") # Add <
|
||||||
|
emphasis = re.compile(r"^\*((?:\*\*|[^\*])+?)\*(?!\*)")
|
||||||
|
double_emphasis = re.compile(r"^\*{2}([\s\S]+?)\*{2}(?!\*)")
|
||||||
|
|
||||||
def plugin_matrix(md):
|
|
||||||
# test string: r"<b>(x) <r>(x) \<a>b>(x) <a\>b>(x) <b>(\(z) <c>(foo\)xyz)"
|
# test string: r"<b>(x) <r>(x) \<a>b>(x) <a\>b>(x) <b>(\(z) <c>(foo\)xyz)"
|
||||||
colour = (
|
color = re.compile(
|
||||||
r"^<(.+?)>" # capture the colour in `<colour>`
|
r"^<(.+?)>" # capture the color in `<color>`
|
||||||
r"\((.+?)" # capture text in `(text`
|
r"\((.+?)" # capture text in `(text`
|
||||||
r"(?<!\\)(?:\\\\)*" # ignore the next `)` if it's \escaped
|
r"(?<!\\)(?:\\\\)*" # ignore the next `)` if it's \escaped
|
||||||
r"\)" # finish on a `)`
|
r"\)", # finish on a `)`
|
||||||
)
|
)
|
||||||
|
|
||||||
# Mark colour as high priority as otherwise e.g. <red>(hi) matches the
|
|
||||||
# inline_html rule instead of the colour rule.
|
|
||||||
md.inline.rules.insert(1, "colour")
|
|
||||||
md.inline.register_rule("colour", colour, parse_colour)
|
|
||||||
|
|
||||||
if md.renderer.NAME == "html":
|
class MarkdownBlockGrammar(mistune.BlockGrammar):
|
||||||
md.renderer.register("colour", render_html_colour)
|
"""Markdown block elements syntax modifications for the Mistune parser.
|
||||||
|
|
||||||
|
- Require a space after # for titles
|
||||||
|
"""
|
||||||
|
|
||||||
|
heading = re.compile(r"^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)")
|
||||||
|
|
||||||
|
|
||||||
|
class MarkdownInlineLexer(mistune.InlineLexer):
|
||||||
|
"""Apply the changes from `MarkdownInlineGrammar` for Mistune."""
|
||||||
|
|
||||||
|
grammar_class = MarkdownInlineGrammar
|
||||||
|
|
||||||
|
default_rules = [
|
||||||
|
"escape", "color", "autolink", "url", # Add color
|
||||||
|
"footnote", "link", "reflink", "nolink",
|
||||||
|
"double_emphasis", "emphasis", "code",
|
||||||
|
"linebreak", "strikethrough", "text",
|
||||||
|
]
|
||||||
|
inline_html_rules = [
|
||||||
|
"escape", "color", "autolink", "url", "link", "reflink", # Add color
|
||||||
|
"nolink", "double_emphasis", "emphasis", "code",
|
||||||
|
"linebreak", "strikethrough", "text",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def output_double_emphasis(self, m):
|
||||||
|
return self.renderer.double_emphasis(self.output(m.group(1)))
|
||||||
|
|
||||||
|
|
||||||
|
def output_emphasis(self, m):
|
||||||
|
return self.renderer.emphasis(self.output(m.group(1)))
|
||||||
|
|
||||||
|
|
||||||
|
def output_color(self, m):
|
||||||
|
color = m.group(1)
|
||||||
|
text = self.output(m.group(2))
|
||||||
|
return self.renderer.color(color, text)
|
||||||
|
|
||||||
|
|
||||||
|
class MarkdownBlockLexer(mistune.BlockLexer):
|
||||||
|
"""Apply the changes from `MarkdownBlockGrammar` for Mistune."""
|
||||||
|
|
||||||
|
grammar_class = MarkdownBlockGrammar
|
||||||
|
|
||||||
|
|
||||||
|
class MarkdownRenderer(mistune.Renderer):
|
||||||
|
def color(self, color: str, text: str) -> str:
|
||||||
|
"""Render given text with a color using `<span data-mx-color=#hex>`."""
|
||||||
|
|
||||||
|
# This may be a SVG color name, try to get a #hex code from it:
|
||||||
|
with suppress(KeyError):
|
||||||
|
color = SVGColor[color.lower().replace(" ", "")].value.hex
|
||||||
|
|
||||||
|
return f'<span data-mx-color="{color}">{text}</span>'
|
||||||
|
|
||||||
|
|
||||||
class HTMLProcessor:
|
class HTMLProcessor:
|
||||||
@ -149,13 +201,19 @@ class HTMLProcessor:
|
|||||||
|
|
||||||
# hard_wrap: convert all \n to <br> without required two spaces
|
# hard_wrap: convert all \n to <br> without required two spaces
|
||||||
# escape: escape HTML characters in the input string, e.g. tags
|
# escape: escape HTML characters in the input string, e.g. tags
|
||||||
self._markdown_to_html = mistune.create_markdown(
|
self._markdown_to_html = mistune.Markdown(
|
||||||
hard_wrap = True,
|
hard_wrap = True,
|
||||||
escape = True,
|
escape = True,
|
||||||
renderer = "html",
|
inline = MarkdownInlineLexer,
|
||||||
plugins = ['strikethrough', plugin_matrix],
|
block = MarkdownBlockLexer,
|
||||||
|
renderer = MarkdownRenderer(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self._markdown_to_html.block.default_rules = [
|
||||||
|
rule for rule in self._markdown_to_html.block.default_rules
|
||||||
|
if rule != "block_quote"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def mentions_in_html(self, html: str) -> List[Tuple[str, str]]:
|
def mentions_in_html(self, html: str) -> List[Tuple[str, str]]:
|
||||||
"""Return list of (text, href) tuples for all mention links in html."""
|
"""Return list of (text, href) tuples for all mention links in html."""
|
||||||
|
Loading…
Reference in New Issue
Block a user