diff --git a/doc/scripts/wikiparser.py b/doc/scripts/wikiparser.py
index 82e14e452..bac732083 100644
--- a/doc/scripts/wikiparser.py
+++ b/doc/scripts/wikiparser.py
@@ -166,10 +166,7 @@ class Paragraph(Element):
xml = ''
for item_xml in items_xml:
- if item_xml[0] in '.,:;-_!?':
- xml += item_xml
- else:
- xml += ' ' + item_xml
+ xml += item_xml
return f'{xml}'
@@ -555,7 +552,6 @@ def split_formatted(text, delimiter, end_delimiter=None):
Return (formatted_text, remaining_text) if it is found.
Return (None, text) otherwise.
"""
- text = text.strip()
end_delimiter = end_delimiter or delimiter
content = None
if text.startswith(delimiter):
@@ -698,7 +694,6 @@ def parse_text(line, context=None, parse_links=True):
content = re.split(r"''|`|{{|__|\[\[", line)[0]
if content:
line = line.replace(content, '', 1)
- content = content.strip()
result += parse_plain_text(content, parse_links=parse_links)
continue
@@ -711,7 +706,6 @@ def parse_plain_text(content, parse_links=True):
"""Parse a line or plain text and generate plain text and URL objects."""
result = []
while content:
- content = content.strip()
wiki_link_match = re.search(
r'(?: |^)([A-Z][a-z0-9]+([A-Z][a-z0-9]+)+)(?: |$)', content)
link_match = re.search(r'(https?://[^<> ]+[^<> .:\(\)])', content)
@@ -737,9 +731,6 @@ def parse_plain_text(content, parse_links=True):
# Replace occurrences of !WikiText with WikiText
text = re.sub(r'([^A-Za-z]|^)!', r'\g<1>', text)
- # Gobble multiple spaces
- text = re.sub(r' +', r' ', text)
-
result.append(PlainText(text))
if end:
@@ -755,8 +746,8 @@ def parse_table_row(line, context=None):
row_cells = re.split(r'\|\|', line)[1:-1]
row_items = []
for cell in row_cells:
- content = cell.strip()
- if content:
+ content = cell
+ if content.strip():
# remove that was already processed
content = re.sub(']+>', '', content)
align = None
@@ -804,8 +795,21 @@ def parse_list(list_data, context=None):
else:
content = list_data.pop(0)[2]
+ new_content = ''
+ in_code_block = False
+ for line in content.splitlines(True):
+ if line.startswith(' ' * current_level) and not in_code_block:
+ line = line[current_level:]
+
+ if line.strip().startswith('{{{'):
+ in_code_block = True
+ elif line.strip().startswith('}}}'):
+ in_code_block = False
+
+ new_content += line
+
parsed_list.add_item(
- ListItem(parse_wiki(content, context),
+ ListItem(parse_wiki(new_content, context),
override_marker=override_marker))
return parsed_list, list_data
@@ -885,91 +889,94 @@ def parse_wiki(text, context=None, begin_marker=None, end_marker=None):
[Heading(5, 'heading 5th level')]
>>> parse_wiki('plain text')
- [Paragraph([PlainText('plain text')])]
+ [Paragraph([PlainText('plain text ')])]
>>> parse_wiki(' plain multispaced text ')
- [Paragraph([PlainText('plain multispaced text')])]
+ [Paragraph([PlainText(' plain multispaced text ')])]
>>> parse_wiki('https://freedombox.org')
- [Paragraph([Url('https://freedombox.org')])]
+ [Paragraph([Url('https://freedombox.org'), PlainText(' ')])]
>>> parse_wiki("''italic''")
- [Paragraph([ItalicText('italic')])]
+ [Paragraph([ItalicText('italic'), PlainText(' ')])]
>>> parse_wiki("'''bold'''")
- [Paragraph([BoldText('bold')])]
+ [Paragraph([BoldText('bold'), PlainText(' ')])]
>>> parse_wiki("normal text followed by '''bold text'''")
- [Paragraph([PlainText('normal text followed by'), BoldText('bold text')])]
+ [Paragraph([PlainText('normal text followed by '), BoldText('bold text'), \
+PlainText(' ')])]
>>> parse_wiki('`monospace`')
- [Paragraph([MonospaceText('monospace')])]
+ [Paragraph([MonospaceText('monospace'), PlainText(' ')])]
>>> parse_wiki('{{{code}}}')
- [Paragraph([CodeText('code')])]
+ [Paragraph([CodeText('code'), PlainText(' ')])]
>>> parse_wiki('__underline__')
- [Paragraph([UnderlineText('underline')])]
+ [Paragraph([UnderlineText('underline'), PlainText(' ')])]
>>> parse_wiki('~-smaller text-~')
- [Paragraph([SmallerTextWarning(), PlainText('smaller text')])]
+ [Paragraph([SmallerTextWarning(), PlainText('smaller text ')])]
>>> parse_wiki('!FreedomBox')
- [Paragraph([PlainText('FreedomBox')])]
+ [Paragraph([PlainText('FreedomBox ')])]
>>> parse_wiki('making a point!')
- [Paragraph([PlainText('making a point!')])]
+ [Paragraph([PlainText('making a point! ')])]
>>> parse_wiki('Back to [[FreedomBox/Manual|manual]] page.')
- [Paragraph([PlainText('Back to'), Link('FreedomBox/Manual', \
-[PlainText('manual')]), PlainText('page.')])]
+ [Paragraph([PlainText('Back to '), Link('FreedomBox/Manual', \
+[PlainText('manual')]), PlainText(' page. ')])]
>>> parse_wiki('[[attachment:Searx.webm|Searx installation and first steps\
|&do=get]]')
[Paragraph([Link('attachment:Searx.webm', \
-[PlainText('Searx installation and first steps')], '&do=get')])]
+[PlainText('Searx installation and first steps')], '&do=get'), \
+PlainText(' ')])]
>>> parse_wiki('[[https://onionshare.org/|Onionshare]]')
- [Paragraph([Link('https://onionshare.org/', [PlainText('Onionshare')])])]
+ [Paragraph([Link('https://onionshare.org/', [PlainText('Onionshare')]), \
+PlainText(' ')])]
>>> parse_wiki('/!\\\\')
[Paragraph([EmbeddedAttachment('icons/alert.png', \
-[PlainText('icons/alert.png')], 'height=20')])]
+[PlainText('icons/alert.png')], 'height=20'), PlainText(' ')])]
>>> parse_wiki('(./)')
[Paragraph([EmbeddedAttachment('icons/checkmark.png', \
-[PlainText('icons/checkmark.png')], 'height=20')])]
+[PlainText('icons/checkmark.png')], 'height=20'), PlainText(' ')])]
>>> parse_wiki('{X}')
[Paragraph([EmbeddedAttachment('icons/icon-error.png', \
-[PlainText('icons/icon-error.png')], 'height=20')])]
+[PlainText('icons/icon-error.png')], 'height=20'), PlainText(' ')])]
>>> parse_wiki('{i}')
[Paragraph([EmbeddedAttachment('icons/icon-info.png', \
-[PlainText('icons/icon-info.png')], 'height=20')])]
+[PlainText('icons/icon-info.png')], 'height=20'), PlainText(' ')])]
>>> parse_wiki('{o}')
[Paragraph([EmbeddedAttachment('icons/star_off.png', \
-[PlainText('icons/star_off.png')], 'height=20')])]
+[PlainText('icons/star_off.png')], 'height=20'), PlainText(' ')])]
>>> parse_wiki('{*}')
[Paragraph([EmbeddedAttachment('icons/star_on.png', \
-[PlainText('icons/star_on.png')], 'height=20')])]
+[PlainText('icons/star_on.png')], 'height=20'), PlainText(' ')])]
>>> parse_wiki('{{attachment:cockpit-enable.png}}')
[Paragraph([EmbeddedAttachment('cockpit-enable.png', \
-[PlainText('cockpit-enable.png')])])]
+[PlainText('cockpit-enable.png')]), PlainText(' ')])]
>>> parse_wiki('{{attachment:Backups_Step1_v49.png|Backups: Step 1|\
width=800}}')
[Paragraph([EmbeddedAttachment('Backups_Step1_v49.png', \
-[PlainText('Backups: Step 1')], 'width=800')])]
+[PlainText('Backups: Step 1')], 'width=800'), PlainText(' ')])]
>>> parse_wiki(' * single item')
- [List('bulleted', [ListItem([Paragraph([PlainText('single item')])])])]
+ [List('bulleted', [ListItem([Paragraph([PlainText('single item ')])])])]
>>> parse_wiki(' * first item\\n * second item')
- [List('bulleted', [ListItem([Paragraph([PlainText('first item')])]), \
-ListItem([Paragraph([PlainText('second item')])])])]
+ [List('bulleted', [ListItem([Paragraph([PlainText('first item ')])]), \
+ListItem([Paragraph([PlainText('second item ')])])])]
>>> parse_wiki('text to introduce\\n * a list')
- [Paragraph([PlainText('text to introduce')]), \
-List('bulleted', [ListItem([Paragraph([PlainText('a list')])])])]
+ [Paragraph([PlainText('text to introduce ')]), \
+List('bulleted', [ListItem([Paragraph([PlainText('a list ')])])])]
>>> parse_wiki(' . first item\\n . second item')
- [List('plain', [ListItem([Paragraph([PlainText('first item')])]), \
-ListItem([Paragraph([PlainText('second item')])])])]
+ [List('plain', [ListItem([Paragraph([PlainText('first item ')])]), \
+ListItem([Paragraph([PlainText('second item ')])])])]
>>> parse_wiki(' * item 1\\n * item 1.1')
- [List('bulleted', [ListItem([Paragraph([PlainText('item 1')]), \
-List('bulleted', [ListItem([Paragraph([PlainText('item 1.1')])])])])])]
+ [List('bulleted', [ListItem([Paragraph([PlainText('item 1 ')]), \
+List('bulleted', [ListItem([Paragraph([PlainText('item 1.1 ')])])])])])]
>>> parse_wiki(' 1. item 1\\n 1. item 1.1')
- [List('numbered', [ListItem([Paragraph([PlainText('item 1')]), \
-List('numbered', [ListItem([Paragraph([PlainText('item 1.1')])])])])])]
+ [List('numbered', [ListItem([Paragraph([PlainText('item 1 ')]), \
+List('numbered', [ListItem([Paragraph([PlainText('item 1.1 ')])])])])])]
>>> parse_wiki(' * single,\\n multiline item')
[List('bulleted', \
-[ListItem([Paragraph([PlainText('single,'), \
-PlainText('multiline item')])])])]
+[ListItem([Paragraph([PlainText('single, '), \
+PlainText('multiline item ')])])])]
>>> parse_wiki(' * single,\\n \\n multipara item')
[List('bulleted', \
-[ListItem([Paragraph([PlainText('single,')]), \
-Paragraph([PlainText('multipara item')])])])]
+[ListItem([Paragraph([PlainText('single, ')]), \
+Paragraph([PlainText('multipara item ')])])])]
>>> parse_wiki('----')
[HorizontalRule(4)]
@@ -980,9 +987,9 @@ Paragraph([PlainText('multipara item')])])])]
[Table([TableRow([TableItem([Paragraph([BoldText('A')])]), \
TableItem([Paragraph([BoldText('B')])]), \
TableItem([Paragraph([BoldText('C')])])]), \
-TableRow([TableItem([Paragraph([PlainText('1')])]), \
-TableItem([Paragraph([PlainText('2')])]), \
-TableItem([Paragraph([PlainText('3')])])])])]
+TableRow([TableItem([Paragraph([PlainText('1 ')])]), \
+TableItem([Paragraph([PlainText('2 ')])]), \
+TableItem([Paragraph([PlainText('3 ')])])])])]
>>> parse_wiki("||A||")
[Table([TableRow([TableItem([Paragraph([PlainText('A')])])])], \
@@ -1020,52 +1027,53 @@ from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>')
>>> parse_wiki('a\\n\\n## END_INCLUDE\\n\\nb', \
None, None, '## END_INCLUDE')
- [Paragraph([PlainText('a')])]
+ [Paragraph([PlainText('a ')])]
>>> parse_wiki('a\\n\\n## BEGIN_INCLUDE\\n\\nb' \
'\\n\\n## END_INCLUDE\\n\\nc', \
None, '## BEGIN_INCLUDE', '## END_INCLUDE')
- [Paragraph([PlainText('b')])]
+ [Paragraph([PlainText('b ')])]
>>> parse_wiki('a<
>\\nb')
- [Paragraph([PlainText('a')]), Paragraph([PlainText('b')])]
+ [Paragraph([PlainText('a')]), Paragraph([PlainText('b ')])]
>>> parse_wiki('{{{#!wiki caution\\n\\nOnce some other app is set as the \
home page, you can only navigate to the !FreedomBox Service (Plinth) by \
typing https://myfreedombox.rocks/plinth/ into the browser. <
>\\n\
-''/freedombox'' can also be used as an alias to ''/plinth''\\n}}}')
+''/freedombox'' can also be used as an alias to ''/plinth''\\n}}}')
[Admonition('caution', [Paragraph([PlainText('Once some other app is set \
as the home page, you can only navigate to the FreedomBox Service (Plinth) by \
-typing '), Url('https://myfreedombox.rocks/plinth/'), PlainText('into the \
-browser.')]), Paragraph([PlainText('/freedombox can also be used as an alias \
+typing '), Url('https://myfreedombox.rocks/plinth/'), PlainText(' into the \
+browser. ')]), Paragraph([PlainText('/freedombox can also be used as an alias \
to /plinth')])])]
>>> parse_wiki('{{{\\nmulti-line\\n\
preformatted text (source code)\\n}}}''')
[CodeText('multi-line\\npreformatted text (source code)')]
>>> parse_wiki('text to introduce {{{ a singleliner}}}')
- [Paragraph([PlainText('text to introduce'), CodeText(' a singleliner')])]
- >>> parse_wiki('text to introduce \\n{{{\\n a multiliner\\nstarting at\
+ [Paragraph([PlainText('text to introduce '), CodeText(' a singleliner'),\
+ PlainText(' ')])]
+ >>> parse_wiki('text to introduce\\n{{{\\n a multiliner\\nstarting at\
\\n different indents.\\n}}}')
- [Paragraph([PlainText('text to introduce')]), \
+ [Paragraph([PlainText('text to introduce ')]), \
CodeText(' a multiliner\\nstarting at\\n different indents.')]
>>> parse_wiki('Blah, blah:\\n {{{\\nmulti-line\\nformatted text\\n\
starting at col #1\\n}}}')
- [Paragraph([PlainText('Blah, blah:')]), \
+ [Paragraph([PlainText('Blah, blah: ')]), \
CodeText('multi-line\\nformatted text\\nstarting at col #1')]
>>> parse_wiki(' * Blah, blah:\\n {{{\\nmulti-line\\nformatted text\
\\nstarting at col #1\\n}}}')
[List('bulleted', \
-[ListItem([Paragraph([PlainText('Blah, blah:')]), \
+[ListItem([Paragraph([PlainText('Blah, blah: ')]), \
CodeText('multi-line\\nformatted text\\nstarting at col #1')])])]
>>> parse_wiki(' {{{\\n nmap -p 80 --open -sV 192.168.0.0/24 \
(replace the ip/netmask with the one the router uses)\\n }}}\\n In \
most cases you can look at your current IP address, and change the last \
digits with zero to find your home network, like so: XXX.XXX.XXX.0/24')
[CodeText(' nmap -p 80 --open -sV 192.168.0.0/24 (replace the \
-ip/netmask with the one the router uses)'), Paragraph([PlainText('In \
+ip/netmask with the one the router uses)'), Paragraph([PlainText(' In \
most cases you can look at your current IP address, and change the last \
-digits with zero to find your home network, like so: XXX.XXX.XXX.0/24')])]
- >>> parse_wiki('text to introduce \\n----\\n<>')
- [Paragraph([PlainText('text to introduce')]), \
+digits with zero to find your home network, like so: XXX.XXX.XXX.0/24 ')])]
+ >>> parse_wiki('text to introduce\\n----\\n<>')
+ [Paragraph([PlainText('text to introduce ')]), \
HorizontalRule(4), TableOfContents()]
>>> parse_wiki(' If this command shows an error such as ''new key but \
@@ -1074,69 +1082,69 @@ the keys:\\n {{{\\n$ gpg --keyserver keys.gnupg.net --recv-keys \
BCBEBD57A11F70B23782BC5736C361440C9BC971\\n$ gpg --keyserver keys.gnupg.net \
--recv-keys 7D6ADB750F91085589484BE677C0C75E7B650808\\n$ gpg --keyserver \
keys.gnupg.net --recv-keys 013D86D8BA32EAB4A6691BF85D4153D6FE188FC8\\n }}}')
- [Paragraph([PlainText('If this command shows an error such as new key but \
-contains no user ID - skipped, then use a different keyserver to download the \
-keys:')]), CodeText('$ gpg --keyserver keys.gnupg.net --recv-keys \
+ [Paragraph([PlainText(' If this command shows an error such as new key \
+but contains no user ID - skipped, then use a different keyserver to download \
+the keys: ')]), CodeText('$ gpg --keyserver keys.gnupg.net --recv-keys \
BCBEBD57A11F70B23782BC5736C361440C9BC971\\n$ gpg --keyserver keys.gnupg.net \
--recv-keys 7D6ADB750F91085589484BE677C0C75E7B650808\\n$ gpg --keyserver \
keys.gnupg.net --recv-keys 013D86D8BA32EAB4A6691BF85D4153D6FE188FC8')]
>>> parse_wiki('User documentation:\\n * List of \
[[FreedomBox/Features|applications]] offered by !FreedomBox.')
- [Paragraph([PlainText('User documentation:')]), List('bulleted', \
-[ListItem([Paragraph([PlainText('List of'), Link('FreedomBox/Features', \
-[PlainText('applications')]), PlainText('offered by FreedomBox.')])])])]
+ [Paragraph([PlainText('User documentation: ')]), List('bulleted', \
+[ListItem([Paragraph([PlainText('List of '), Link('FreedomBox/Features', \
+[PlainText('applications')]), PlainText(' offered by FreedomBox. ')])])])]
>>> parse_wiki('\
* Within !FreedomBox Service (Plinth)\\n\
1. select ''Apps''\\n\
- 2. go to ''Radicale (Calendar and Addressbook)'' and \\n\
+ 2. go to ''Radicale (Calendar and Addressbook)'' and\\n\
3. install the application. After the installation is complete, make sure \
the application is marked "enabled" in the !FreedomBox interface. Enabling \
-the application launches the Radicale CalDAV/CardDAV server. \\n\
+the application launches the Radicale CalDAV/CardDAV server.\\n\
4. define the access rights:\\n\
* Only the owner of a calendar/addressbook can view or make changes\\n\
* Any user can view any calendar/addressbook, but only the owner can make \
changes\\n\
* Any user can view or make changes to any calendar/addressbook')
[List('bulleted', [\
-ListItem([Paragraph([PlainText('Within FreedomBox Service (Plinth)')]), \
-List('numbered', [ListItem([Paragraph([PlainText('select Apps')])]), \
+ListItem([Paragraph([PlainText('Within FreedomBox Service (Plinth) ')]), \
+List('numbered', [ListItem([Paragraph([PlainText('select Apps ')])]), \
ListItem([Paragraph([PlainText('go to Radicale (Calendar and Addressbook) \
-and')])]), \
+and ')])]), \
ListItem([Paragraph([PlainText('install the application. After the \
installation is complete, make sure the application is marked "enabled" in \
the FreedomBox interface. Enabling the application launches the Radicale \
-CalDAV/CardDAV server.')])]), \
-ListItem([Paragraph([PlainText('define the access rights:')]), \
+CalDAV/CardDAV server. ')])]), \
+ListItem([Paragraph([PlainText('define the access rights: ')]), \
List('bulleted', [ListItem([Paragraph([PlainText('Only the owner of a \
-calendar/addressbook can view or make changes')])]), \
+calendar/addressbook can view or make changes ')])]), \
ListItem([Paragraph([PlainText('Any user can view any calendar/addressbook, \
-but only the owner can make changes')])]), \
+but only the owner can make changes ')])]), \
ListItem([Paragraph([PlainText('Any user can view or make changes to any \
-calendar/addressbook')])])])])])])])]
+calendar/addressbook ')])])])])])])])]
>>> parse_wiki('[[attachment:freedombox-screenshot-home.png|\
{{attachment:freedombox-screenshot-home.png|Home Page|width=300}}]]')
[Paragraph([Link('attachment:freedombox-screenshot-home.png', \
[EmbeddedAttachment('freedombox-screenshot-home.png', \
-[PlainText('Home Page')], 'width=300')])])]
+[PlainText('Home Page')], 'width=300')]), PlainText(' ')])]
>>> parse_wiki(" * New wiki and manual content licence: \
''[[https://creativecommons.org/licenses/by-sa/4.0/|Creative Commons \
Attribution-ShareAlike 4.0 International]]'' (from June 13rd 2016).")
[List('bulleted', [ListItem([Paragraph([PlainText('New wiki and manual \
-content licence:'), Link('https://creativecommons.org/licenses/by-sa/4.0/', \
+content licence: '), Link('https://creativecommons.org/licenses/by-sa/4.0/', \
[ItalicText('Creative Commons Attribution-ShareAlike 4.0 International')]), \
-PlainText('(from June 13rd 2016).')])])])]
+PlainText(' (from June 13rd 2016). ')])])])]
>>> parse_wiki('An alternative to downloading these images is to \
[[InstallingDebianOn/TI/BeagleBone|install Debian]] on the !BeagleBone and \
then [[FreedomBox/Hardware/Debian|install FreedomBox]] on it.')
- [Paragraph([PlainText('An alternative to downloading these images is to'),\
- Link('InstallingDebianOn/TI/BeagleBone', [PlainText('install Debian')]), \
-PlainText('on the BeagleBone and then'), Link('FreedomBox/Hardware/Debian', \
-[PlainText('install FreedomBox')]), PlainText('on it.')])]
+ [Paragraph([PlainText('An alternative to downloading these images is to ')\
+, Link('InstallingDebianOn/TI/BeagleBone', [PlainText('install Debian')]), \
+PlainText(' on the BeagleBone and then '), Link('FreedomBox/Hardware/Debian', \
+[PlainText('install FreedomBox')]), PlainText(' on it. ')])]
>>> parse_wiki("'''Synchronizing contacts'''\\n 1. Click on the hamburger \
menus of CalDAV and CardDAV and select either \\"Refresh ...\\" in case of \
@@ -1144,13 +1152,14 @@ existing accounts or \\"Create ...\\" in case of new accounts (see the second \
screenshot below).\\n 1. Check the checkboxes for the address books and \
calendars you want to synchronize and click on the sync button in the header. \
(see the third screenshot below)")
- [Paragraph([BoldText('Synchronizing contacts')]), List('numbered', \
+ [Paragraph([BoldText('Synchronizing contacts'), PlainText(' ')]), \
+List('numbered', \
[ListItem([Paragraph([PlainText('Click on the hamburger menus of CalDAV and \
CardDAV and select either "Refresh ..." in case of existing accounts or \
-"Create ..." in case of new accounts (see the second screenshot below).')])]),\
+"Create ..." in case of new accounts (see the second screenshot below). ')])]),\
ListItem([Paragraph([PlainText('Check the checkboxes for the address books \
and calendars you want to synchronize and click on the sync button in the \
-header. (see the third screenshot below)')])])])]
+header. (see the third screenshot below) ')])])])]
>>> parse_wiki("After Roundcube is installed, it can be accessed at \
{{{https:///roundcube}}}. Enter your username and password. \
@@ -1164,19 +1173,19 @@ the IMAP server. Using encrypted connection to your IMAP server is strongly \
recommended. To do this, prepend 'imaps://' at the beginning of your IMAP \
server address. For example, ''imaps://imap.example.org''.")
[Paragraph([PlainText('After Roundcube is installed, it can be accessed \
-at'), CodeText('https:///roundcube'), PlainText('. Enter \
+at '), CodeText('https:///roundcube'), PlainText('. Enter \
your username and password. The username for many mail services will be the \
-full email address such as'), ItalicText('exampleuser@example.org'), \
-PlainText('and not just the username like'), ItalicText('exampleuser'), \
+full email address such as '), ItalicText('exampleuser@example.org'), \
+PlainText(' and not just the username like '), ItalicText('exampleuser'), \
PlainText(". Enter the address of your email service's IMAP server address in \
-the"), ItalicText('Server'), PlainText('field. You can try providing your \
-domain name here such as'), ItalicText('example.org'), PlainText('for email \
-address'), ItalicText('exampleuser@example.org'), PlainText("and if this does \
-not work, consult your email provider's documentation for the address of the \
-IMAP server. Using encrypted connection to your IMAP server is strongly \
-recommended. To do this, prepend 'imaps://' at the beginning of your IMAP \
-server address. For example,"), ItalicText('imaps://imap.example.org'), \
-PlainText('.')])]
+the "), ItalicText('Server'), PlainText(' field. You can try providing your \
+domain name here such as '), ItalicText('example.org'), PlainText(' for email \
+address '), ItalicText('exampleuser@example.org'), PlainText(" and if this \
+does not work, consult your email provider's documentation for the address \
+of the IMAP server. Using encrypted connection to your IMAP server is \
+strongly recommended. To do this, prepend 'imaps://' at the beginning of \
+your IMAP server address. For example, "), \
+ItalicText('imaps://imap.example.org'), PlainText('. ')])]
>>> parse_wiki('Tor Browser is the recommended way to browse the web \
using Tor. You can download the Tor Browser from \
@@ -1184,19 +1193,19 @@ https://www.torproject.org/projects/torbrowser.html and follow the \
instructions on that site to install and run it.')
[Paragraph([PlainText('Tor Browser is the recommended way to browse the \
web using Tor. You can download the Tor Browser from '), Url('\
-https://www.torproject.org/projects/torbrowser.html'), PlainText('and follow \
-the instructions on that site to install and run it.')])]
+https://www.torproject.org/projects/torbrowser.html'), PlainText(' and follow \
+the instructions on that site to install and run it. ')])]
>>> parse_wiki('After installation a web page becomes available on \
https:///_minidlna.')
[Paragraph([PlainText('After installation a web page becomes available on \
-https:///_minidlna.')])]
+https:///_minidlna. ')])]
>>> parse_wiki('or http://10.42.0.1/.')
- [Paragraph([PlainText('or '), Url('http://10.42.0.1/'), PlainText('.')])]
+ [Paragraph([PlainText('or '), Url('http://10.42.0.1/'), PlainText('. ')])]
>>> parse_wiki('or http://10.42.0.1/:')
- [Paragraph([PlainText('or '), Url('http://10.42.0.1/'), PlainText(':')])]
+ [Paragraph([PlainText('or '), Url('http://10.42.0.1/'), PlainText(': ')])]
>>> parse_wiki('||