Skip to content

Commit

Permalink
Merge pull request #11 from wgxli/develop
Browse files Browse the repository at this point in the history
Additional unit tests, under-the-hood changes
  • Loading branch information
wgxli committed Aug 6, 2018
2 parents d5fb659 + b5d7e0b commit 3937860
Show file tree
Hide file tree
Showing 19 changed files with 336 additions and 37 deletions.
1 change: 0 additions & 1 deletion .gitignore
Expand Up @@ -4,4 +4,3 @@ docs/build
__pycache__/
.coverage
cover
run_tests.bat
6 changes: 3 additions & 3 deletions .travis.yml
Expand Up @@ -3,10 +3,10 @@ python:
- '3.3'
- '3.4'
- '3.5'
- '3.6-dev'
- 'nightly'
- '3.6'
- '3.7-dev'
install:
- pip install coveralls
script: nosetests --with-coverage --cover-branch --cover-package=simpletex
after_success:
- coveralls
- coveralls
2 changes: 1 addition & 1 deletion docs/source/index.rst
Expand Up @@ -24,6 +24,7 @@ Getting Started

install
tutorial
examples

API Documentation
-----------------
Expand All @@ -32,4 +33,3 @@ API Documentation

core_latex
xetex
third_party
2 changes: 1 addition & 1 deletion docs/source/install.rst
Expand Up @@ -5,4 +5,4 @@ The easiest way to install simpletex is through the Python Package Index (PyPI).

.. code-block:: bash
pip install simpletex
pip3 install simpletex
1 change: 1 addition & 0 deletions make-docs.sh
@@ -0,0 +1 @@
sphinx-build -b html docs/source docs/build
1 change: 1 addition & 0 deletions run-tests.sh
@@ -0,0 +1 @@
nosetests --with-coverage --cover-branch --cover-html --cover-package=simpletex
12 changes: 6 additions & 6 deletions simpletex/__init__.py
Expand Up @@ -53,9 +53,9 @@ def top(self):
"""Return the context at the top of the current context stack."""
return self.contextStack[-1]

def write(self, text):
"""Write the given text to the top-level context."""
self.top.write(text)
def write(self, *args, **kwargs):
"""Write the given text or parameters to the top-level context."""
self.top.write(*args, **kwargs)

def save(self, name):
"""Save the entire document under the given filename."""
Expand Down Expand Up @@ -106,9 +106,9 @@ def latex_escape(text) -> str:
for char in str(text))


def write(text):
"""Write the given text to the current top-level context."""
_CONTEXT.write(text)
def write(*args, **kwargs):
"""Write the given text or parameters to the current top-level context."""
_CONTEXT.write(*args, **kwargs)


def write_break(text):
Expand Down
5 changes: 3 additions & 2 deletions simpletex/base.py
Expand Up @@ -61,10 +61,11 @@ def __str__(self):


class Environment(Formatter):
def __init__(self, name=None):
def __init__(self, name=None, *args):
super().__init__()
if name is not None:
self.header = Command('begin', [name])
# [name, *args] not supported in Python 3.4 and below
self.header = Command('begin', [name] + list(args))
self.footer = Command('end', [name])

def _format_text(self, text) -> str:
Expand Down
11 changes: 7 additions & 4 deletions simpletex/core.py
Expand Up @@ -31,7 +31,7 @@ def __call__(self, *args, **kwargs) -> str:
# Should be overridden by subclasses
@staticmethod
def _format_text(text) -> str:
return text
return str(text)

def __enter__(self):
"""Add self to the global context stack."""
Expand Down Expand Up @@ -125,9 +125,12 @@ def __len__(self):
"""Return the number of text segments stored."""
return len(self._text)

def write(self, text):
"""Append the given text segment to the paragraph."""
self._text.append(text)
def write(self, *args, **kwargs):
"""Append the given text segment or parameters to the paragraph."""
if len(args) == 1:
self._text.append(args[0])
else:
self._text.append(args)

def __str__(self):
"""Return all text segments, joined with newlines."""
Expand Down
9 changes: 6 additions & 3 deletions simpletex/formatting/layout.py
Expand Up @@ -32,7 +32,7 @@ def __init__(self, inline: bool = False):

def _format_text(self, text) -> str:
if self._inline:
return '{}{}'.format(Command('centering'), text)
return '{} {}'.format(Command('centering'), text)
else:
return super()._format_text(text)

Expand All @@ -44,7 +44,7 @@ class Columns(Environment):
Equivalent to the LaTeX ``multicols`` environment.
"""

def __init__(self, number: int):
def __init__(self, number: int = 2):
"""
Create a new ``multicols`` environment.
Expand All @@ -53,5 +53,8 @@ def __init__(self, number: int):
number : int
The number of columns to use.
"""
super().__init__('multicols')
if number == 2:
super().__init__('multicols')
else:
super().__init__('multicols', number)
usepackage('multicol')
15 changes: 6 additions & 9 deletions simpletex/formatting/text.py
Expand Up @@ -38,7 +38,7 @@ def __init__(self,

def _format_text(self, text) -> str:
if self._inline:
return '{}{}'.format(Command(self.inline_name),
return '{} {}'.format(Command(self.inline_name),
text)
else:
return Command(self.command_name, [text])
Expand All @@ -56,7 +56,7 @@ def __init__(self, inline: bool = False):
of the formatter is used.
Otherwise, use the default (``\textbf{}``) version.
"""
super().__init__('textbf', 'bfshape', inline)
super().__init__('textbf', 'bfseries', inline)


class Italics(SimpleFormatter):
Expand All @@ -77,16 +77,13 @@ def __init__(self, inline: bool = False):
class Underline(SimpleFormatter):
"""Applies underline formatting to text."""

def __init__(self, inline: bool = False):
def __init__(self):
r"""
Create a new underline formatter.
inline : bool
If true, the inline (TeX directive) version
of the formatter is used.
Otherwise, use the default (LaTeX command) version.
Note that inline formatting is not supported for underlines.
"""
super().__init__('underline', 'underline', inline)
super().__init__('underline', None, False)


class SmallCaps(SimpleFormatter):
Expand Down
16 changes: 10 additions & 6 deletions simpletex/sequences.py
Expand Up @@ -19,16 +19,20 @@ def _format_text(text) -> str:
"""
Format the given text into a LaTeX item list.
text : iterable of pairs or iterable of items
If pairs are given, the first entry in the pair will be used
as the item key, and the second as the value.
text : iterable of pairs, mapping, or iterable of items
If pairs or a mapping are given, the first component of each entry
will be used as the item key, and the second as the value.
Otherwise, do not use a key in the item command.
"""
try:
return '\n'.join(r'\item[{}] {}'.format(key, item)
for key, item in text)
except ValueError:
return '\n'.join(r'\item {}'.format(item) for item in text)
for key, item in text.items())
except AttributeError:
try:
return '\n'.join(r'\item[{}] {}'.format(key, item)
for key, item in text)
except ValueError:
return '\n'.join(r'\item {}'.format(item) for item in text)


class OrderedList(Environment):
Expand Down
6 changes: 6 additions & 0 deletions temp.py
@@ -0,0 +1,6 @@
from simpletex import write, dump
from simpletex.sequences import Description

with Description():
write('asdf', 'fdsa')
print(dump())
File renamed without changes.
13 changes: 12 additions & 1 deletion tests/test_core.py
Expand Up @@ -10,7 +10,6 @@
class TestFormatter(unittest.TestCase):
def setUp(self):
self.formatter = Formatter()
clear()

def test_call(self):
self.assertEqual(self.formatter(SAMPLE_TEXT),
Expand All @@ -24,6 +23,9 @@ def test_context_manager(self):
write(SAMPLE_TEXT)
self.assertEqual(dump(), SAMPLE_TEXT)

def tearDown(self):
clear()


class TestText(unittest.TestCase):
def setUp(self):
Expand Down Expand Up @@ -82,6 +84,9 @@ def test_context_manager(self):
self.assertRaises(TypeError, self.text.__enter__)
self.assertEqual(self.text.__exit__(), None)

def tearDown(self):
clear()


class TestParagraph(unittest.TestCase):
def setUp(self):
Expand Down Expand Up @@ -116,6 +121,9 @@ def test_context_manager(self):
self.assertRaises(TypeError, self.par.__enter__)
self.assertEqual(self.par.__exit__(), None)

def tearDown(self):
clear()


class TestRegistry(unittest.TestCase):
COMPLEX_OBJECT = {'A': ['B', ('C', 'D')], 'E': None, False: 'F'}
Expand Down Expand Up @@ -163,3 +171,6 @@ def test_str_empty(self):
def test_str_nonempty(self):
self.register_entries()
self.assertEqual(str(self.reg), 'A\nB')

def tearDown(self):
clear()
69 changes: 69 additions & 0 deletions tests/test_document.py
@@ -0,0 +1,69 @@
import unittest
import string

from simpletex import write, clear, dump, save
from simpletex.document import Document, Section, Subsection


SAMPLE_TEXT = 'simpletex'
SAMPLE_HEADING = 'Heading Text'

HEADER = '\n'.join([r'\documentclass[12pt]{article}', '', r'\usepackage[utf8]{inputenc}', '', r'\begin{document}'])
FOOTER = r'\end{document}'


class TestDocument(unittest.TestCase):
def test_document(self):
with Document():
write(SAMPLE_TEXT)
expected_string = '\n'.join([
HEADER,
'\t' + SAMPLE_TEXT,
FOOTER
])
self.assertEqual(dump(),
expected_string)
clear()

def tearDown(self):
clear()


class TestSection(unittest.TestCase):
def test_section(self):
with Document():
with Section(SAMPLE_HEADING):
write(SAMPLE_TEXT)
expected_string = '\n'.join([
HEADER,
'\t\\section{' + SAMPLE_HEADING + '}',
'\t\t' + SAMPLE_TEXT,
FOOTER
])
self.assertEqual(dump(),
expected_string)
clear()

def tearDown(self):
clear()


class TestSubsection(unittest.TestCase):
def test_subsection(self):
with Document():
with Subsection(SAMPLE_HEADING):
write(SAMPLE_TEXT)
expected_string = '\n'.join([
HEADER,
'\t\\subsection{' + SAMPLE_HEADING + '}',
'\t\t' + SAMPLE_TEXT,
FOOTER
])
self.assertEqual(dump(),
expected_string)
clear()

def tearDown(self):
clear()


0 comments on commit 3937860

Please sign in to comment.