Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions snakemd/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from .document import *


def new_doc() -> Document:
"""
Creates a new SnakeMD document. This is a convenience function
Expand All @@ -10,11 +11,10 @@ def new_doc() -> Document:
will need to be imported as needed.

.. code-block:: Python

doc = snakemd.new_doc()

.. versionadded:: 0.9.0

:return: a new Document object
:return:
a new Document object
"""
return Document()
139 changes: 95 additions & 44 deletions snakemd/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,31 @@ class Document:
markdown file. However, the functionality is not exhaustive.
To get the full range of markdown functionality, you can
take advantage of the :func:`add_block` function to provide
custom markdown block.
custom markdown blocks.

All methods described in the Document class include sample
code. Sample code assumes a generic :code:`doc` object exists,
which can be created as follows:

.. code-block:: Python

import snakemd
doc = snakemd.new_doc()
"""

def __init__(self) -> None:
self._contents: list[Block] = list()
logger.debug("New document initialized")

def __str__(self):
"""
Renders the markdown document from a list of blocks.

:return: the document as a markdown string
:return:
the document as a markdown string
"""
return "\n\n".join(str(block) for block in self._contents)

def add_block(self, block: Block) -> Block:
"""
A generic function for appending blocks to the document.
Expand All @@ -43,28 +54,33 @@ def add_block(self, block: Block) -> Block:

.. code-block:: Python

doc.add_block(Heading("Python is Cool!"), 2))
doc.add_block(Heading("Python is Cool!", 2))

:param Block block: a markdown block (e.g., Table, Heading, etc.)
:return: the Block added to this Document
:param Block block:
a markdown block (e.g., Table, Heading, etc.)
:return:
the Block added to this Document
"""
self._contents.append(block)
logger.debug(f"Added block to document\n{block}")
logger.debug(f"Added custom block to document\n{block}")
return block

def add_raw(self, text: str) -> Raw:
"""
A convenience method which adds text as-is to the document:

.. code-block:: Python

doc.add_raw("X: 5\\nY: 4\\nZ: 3")

:param str text: some text
:return: the Raw block added to this Document
:param str text:
some text
:return:
the Raw block added to this Document
"""
raw = Raw(text)
self._contents.append(raw)
logger.debug(f"Added raw block to document\n{text}")
return raw

def add_heading(self, text: str, level: int = 1) -> Heading:
Expand All @@ -75,9 +91,12 @@ def add_heading(self, text: str, level: int = 1) -> Heading:

doc.add_heading("Welcome to SnakeMD!")

:param str text: the text for the heading
:param int level: the level of the heading from 1 to 6
:return: the Heading added to this Document
:param str text:
the text for the heading
:param int level:
the level of the heading from 1 to 6
:return:
the Heading added to this Document
"""
heading = Heading(Inline(text), level)
self._contents.append(heading)
Expand All @@ -92,8 +111,10 @@ def add_paragraph(self, text: str) -> Paragraph:

doc.add_paragraph("Mitochondria is the powerhouse of the cell.")

:param str text: any arbitrary text
:return: the Paragraph added to this Document
:param str text:
any arbitrary text
:return:
the Paragraph added to this Document
"""
paragraph = Paragraph([Inline(text)])
self._contents.append(paragraph)
Expand All @@ -108,8 +129,10 @@ def add_ordered_list(self, items: Iterable[str]) -> MDList:

doc.add_ordered_list(["Goku", "Piccolo", "Vegeta"])

:param Iterable[str] items: a "list" of strings
:return: the MDList added to this Document
:param Iterable[str] items:
a "list" of strings
:return:
the MDList added to this Document
"""
md_list = MDList([Inline(item) for item in items], ordered=True)
self._contents.append(md_list)
Expand All @@ -124,8 +147,10 @@ def add_unordered_list(self, items: Iterable[str]) -> MDList:

doc.add_unordered_list(["Deku", "Bakugo", "Kirishima"])

:param Iterable[str] items: a "list" of strings
:return: the MDList added to this Document
:param Iterable[str] items:
a "list" of strings
:return:
the MDList added to this Document
"""
md_list = MDList([Inline(item) for item in items])
self._contents.append(md_list)
Expand All @@ -140,8 +165,10 @@ def add_checklist(self, items: Iterable[str]) -> MDList:

doc.add_checklist(["Okabe", "Mayuri", "Kurisu"])

:param Iterable[str] items: a "list" of strings
:return: the MDCheckList added to this Document
:param Iterable[str] items:
a "list" of strings
:return:
the MDCheckList added to this Document
"""
md_checklist = MDList([Inline(item) for item in items], checked=False)
self._contents.append(md_checklist)
Expand Down Expand Up @@ -170,12 +197,17 @@ def add_table(
0
)

:param Iterable[str] header: a "list" of strings
:param Iterable[Iterable[str]] data: a "list" of "lists" of strings
:param Iterable[Table.Align] align: a "list" of column alignment values;
:param Iterable[str] header:
a "list" of strings
:param Iterable[Iterable[str]] data:
a "list" of "lists" of strings
:param Iterable[Table.Align] align:
a "list" of column alignment values;
defaults to None
:param int indent: indent size for the whole table
:return: the Table added to this Document
:param int indent:
indent size for the whole table
:return:
the Table added to this Document
"""
header = [Paragraph([text]) for text in header]
data = [[Paragraph([item]) for item in row] for row in data]
Expand All @@ -192,9 +224,12 @@ def add_code(self, code: str, lang: str = "generic") -> Code:

doc.add_code("x = 5")

:param str code: a preformatted code string
:param str lang: the language for syntax highlighting
:return: the Code block added to this Document
:param str code:
a preformatted code string
:param str lang:
the language for syntax highlighting
:return:
the Code block added to this Document
"""
code_block = Code(code, lang=lang)
self._contents.append(code_block)
Expand All @@ -209,8 +244,10 @@ def add_quote(self, text: str) -> Quote:

doc.add_quote("Welcome to the Internet!")

:param str text: the text to be quoted
:return: the Quote added to this Document
:param str text:
the text to be quoted
:return:
the Quote added to this Document
"""
quote = Quote(text)
self._contents.append(quote)
Expand All @@ -225,7 +262,8 @@ def add_horizontal_rule(self) -> HorizontalRule:

doc.add_horizontal_rule()

:return: the HorizontalRule added to this Document
:return:
the HorizontalRule added to this Document
"""
hr = HorizontalRule()
self._contents.append(hr)
Expand All @@ -244,38 +282,50 @@ def add_table_of_contents(self, levels: range = range(2, 3)) -> TableOfContents:

doc.add_table_of_contents()

:param range levels: a range of heading levels to be included in the table of contents
:return: the TableOfContents added to this Document
:param range levels:
a range of heading levels to be included in the table of contents
:return:
the TableOfContents added to this Document
"""
toc = TableOfContents(self, levels=levels)
self._contents.append(toc)
logger.debug(f"Added table of contents to document (unable to render until file is complete)")
logger.debug(
f"Added table of contents to document (unable to render until file is complete)"
)
return toc

def scramble(self) -> None:
"""
A silly method which mixes all of the blocks in this document in
a random order.

.. code-block:: Python

doc.scramble()
"""
random.shuffle(self._contents)
logger.debug(f"Scrambled document")

def dump(self, name: str, dir: str | os.PathLike = "", ext: str = "md", encoding: str = "utf-8") -> None:
"""
Outputs the markdown document to a file. This method assumes the output directory
is the current working directory. Any alternative directory provided will be
made if it does not already exist. This method also assumes a file extension of md
and a file encoding of utf-8, all of which are configurable through the method
parameters.

.. code-block:: Python

doc.dump("README")

:param str name: the name of the markdown file to output without the file extension
:param str | os.PathLike dir: the output directory for the markdown file; defaults to ""
:param str ext: the output file extension; defaults to "md"
:param str encoding: the encoding to use; defaults to utf-8

:param str name:
the name of the markdown file to output without the file extension
:param str | os.PathLike dir:
the output directory for the markdown file; defaults to ""
:param str ext:
the output file extension; defaults to "md"
:param str encoding:
the encoding to use; defaults to utf-8
"""
pathlib.Path(dir).mkdir(parents=True, exist_ok=True)
with open(
Expand All @@ -284,3 +334,4 @@ def dump(self, name: str, dir: str | os.PathLike = "", ext: str = "md", encoding
encoding=encoding
) as output_file:
output_file.write(str(self))
logger.debug(f"Dumped document to {dir} with filename {name}.{ext}")
Loading