Skip to content

Commit

Permalink
Upgrade SnakeMD to 0.5.0 (#28)
Browse files Browse the repository at this point in the history
* Added plausible

* Incremented version

* Added favicon

* Added logo

* Added a verify URLs method

* Modified insert_link function

* Added missing docs

* Fixed implementation of multiple insert

* Found bug with tests

* Added limit test

* Added new replace function

* Added missing info the version history

* Ran a quick reformat
  • Loading branch information
jrg94 committed Jul 21, 2021
1 parent 1bd80ec commit 4a88d74
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 26 deletions.
Binary file added docsrc/_static/favicon.ico
Binary file not shown.
Binary file added docsrc/_static/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions docsrc/_templates/layout.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{% extends "!layout.html" %}
{%- block extrahead %}
<script defer data-domain="snakemd.therenegadecoder.com" src="https://plausible.io/js/plausible.js"></script>
{% endblock %}
4 changes: 2 additions & 2 deletions docsrc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@

github_url = "https://github.com/TheRenegadeCoder/SnakeMD"
html_logo = "_static/icon.png"
html_favicon = '_static/favicon.ico'
issues_github_path = "TheRenegadeCoder/SnakeMD"

html_theme_options = {
"display_version": True
}

issues_github_path = "TheRenegadeCoder/SnakeMD"
8 changes: 8 additions & 0 deletions docsrc/version-history.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ In an effort to keep history of all the documentation
for SnakeMD, we've included all old versions below
as follows:

* `v0.5.0 <https://snakemd.therenegadecoder.com/v0.5.0/>`_
* Added favicon to docs (:issue:`26`)
* Added mass URL verification function to Paragraph class (:issue:`27`)
* Expanded testing to ensure code works as expected
* Changed behavior of insert_link() to mimic str.replace() (:issue:`19`)
* Added a replace method to Paragraph (:issue:`27`)
* Added plausible tracking to latest version of docs (:issue:`25`)

* `v0.4.1 <https://snakemd.therenegadecoder.com/v0.4.1/>`_
* Added support for Python logging library (:issue:`22`)
* Expanded support for strings in the Header, Paragraph, and MDList classes
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
long_description = fh.read()

MAJOR = 0
MINOR = 4
PATCH = 1
MINOR = 5
PATCH = 0

name = "SnakeMD"
version = f"{MAJOR}.{MINOR}"
Expand Down
114 changes: 93 additions & 21 deletions snake/md.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,14 @@ def is_text(self) -> bool:
"""
return not (self._code or self._image or self._url)

def is_url(self) -> bool:
"""
Checks if the InlineText object represents a URL.
:return: True if the object has a URL; False otherwise
"""
return bool(self._url)

def bold(self) -> None:
"""
Adds bold styling to self.
Expand Down Expand Up @@ -434,26 +442,88 @@ def is_text(self) -> bool:
"""
return not (self._code or self._quote)

def insert_link(self, target: str, url: str) -> Paragraph:
def _replace_any(self, target: str, text: InlineText, count: int = -1) -> Paragraph:
"""
Given a target string, this helper method replaces it with the specified
InlineText object. This method was created because insert_link and
replace were literally one line different. This method serves as the
mediator. Note that using this method will introduce several new
underlying InlineText objects even if they could be aggregated.
At some point, we may just expose this method because it seems handy.
For example, I foresee a need for a function where all the person wants
to do is add italics for every instance of a particular string.
Though, I suppose we could include all of that in the default replace
method.
:param str target: the target string to replace
:param InlineText text: the InlineText object to insert in place of the target
:param int count: the number of links to insert; defaults to -1
:return: self
"""
i = 0
content = []
for inline_text in self._content:
if inline_text.is_text() and len(items := inline_text._text.split(target)) > 1:
for item in items:
content.append(InlineText(item))
if count == -1 or i < count:
content.append(text)
i += 1
else:
content.append(InlineText(target))
content.pop()
else:
content.append(inline_text)
self._content = content
return self

def replace(self, target: str, replacement: str, count: int = -1) -> Paragraph:
"""
A convenience method which inserts a link in the paragraph
at the first instance of a target string.
A convenience method which replaces a target string with a string of
the users choice. Like insert_link, this method is modeled after
:code:`str.replace()` of the standard library. As a result, a count
can be provided to limit the number of strings replaced in the paragraph.
.. versionadded:: 0.5.0
:param str target: the target string to replace
:param str replacement: the InlineText object to insert in place of the target
:param int count: the number of links to insert; defaults to -1
:return: self
"""
return self._replace_any(target, InlineText(replacement), count)

def insert_link(self, target: str, url: str, count: int = -1) -> Paragraph:
"""
A convenience method which inserts links in the paragraph
for all matching instances of a target string. This method
is modeled after :code:`str.replace()`, so a count can be
provided to limit the number of insertions.
.. versionadded:: 0.2.0
.. versionchanged:: 0.5.0
Changed function to insert links at all instances of target
rather than just the first instance
:param str target: the string to link
:param str url: the url to link
:param int count: the number of links to insert; defaults to -1
:return: self
"""
content = self._content[:]
for i, inline_text in enumerate(content):
if inline_text.is_text() and len(items := inline_text._text.split(target, 1)) > 1:
self._content.pop(i)
self._content.insert(i, InlineText(items[1]))
self._content.insert(i, InlineText(target, url=url))
self._content.insert(i, InlineText(items[0]))
break
return self
return self._replace_any(target, InlineText(target, url=url), count)

def verify_urls(self) -> dict[str, bool]:
"""
Verifies all URLs in the paragraph. Results are
returned in a dictionary where the URLs are
mapped to their validity.
:return: a dictionary of URLs mapped to their validity
"""
result = {}
for item in self._content:
result[item._url] = item.is_url() and item.verify_url()
return result


class MDList(Element):
Expand Down Expand Up @@ -590,14 +660,15 @@ class Table(Element):
"""

def __init__(
self,
header: Iterable[Union[str, InlineText, Paragraph]],
self,
header: Iterable[Union[str, InlineText, Paragraph]],
body: Iterable[Iterable[Union[str, InlineText, Paragraph]]],
align: Iterable[Align] = None
) -> None:
) -> None:
logger.debug(f"Initializing table\n{(header, body, align)}")
super().__init__()
self._header, self._body, self._widths = self._process_table(header, body)
self._header, self._body, self._widths = self._process_table(
header, body)
self._align = align

class Align(Enum):
Expand Down Expand Up @@ -672,7 +743,8 @@ def render(self) -> str:
]
rows.append(f"| {' | '.join(header)} |")
if not self._align:
rows.append(f"| {' | '.join('-' * width for width in self._widths)} |")
rows.append(
f"| {' | '.join('-' * width for width in self._widths)} |")
else:
meta = []
for align, width in zip(self._align, self._widths):
Expand Down Expand Up @@ -865,11 +937,11 @@ def add_unordered_list(self, items: Iterable[str]) -> MDList:
return md_list

def add_table(
self,
header: Iterable[str],
data: Iterable[Iterable[str]],
self,
header: Iterable[str],
data: Iterable[Iterable[str]],
align: Iterable[Table.Align] = None
) -> Table:
) -> Table:
"""
A convenience method which adds a simple table to the document:
Expand Down
21 changes: 20 additions & 1 deletion tests/test_paragraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,26 @@ def test_paragraph_add_str():
assert str(paragraph) == "HowNowBrownCow"


def test_insert_link():
def test_insert_link_one():
paragraph = Paragraph([InlineText("Check out Google!")]) \
.insert_link("Google", "https://google.com")
assert str(paragraph) == "Check out [Google](https://google.com)!"


def test_insert_link_two_chained():
paragraph = Paragraph(["Hello, World!"]) \
.insert_link("Hello", "A") \
.insert_link("World", "B")
assert str(paragraph) == "[Hello](A), [World](B)!"


def test_insert_link_two_same():
paragraph = Paragraph(["Hello, Hello!"]) \
.insert_link("Hello", "A")
assert str(paragraph) == "[Hello](A), [Hello](A)!"


def test_insert_link_two_limit():
paragraph = Paragraph(["Hello, Hello!"]) \
.insert_link("Hello", "A", count=1)
assert str(paragraph) == "[Hello](A), Hello!"

0 comments on commit 4a88d74

Please sign in to comment.