Skip to content

Commit

Permalink
Trac #18357: Unicode Art
Browse files Browse the repository at this point in the history
There should be a variant of ascii art using unicode. It should share
code with ascii art as appropriate.

Also, there are various typesetting-related modules in `sage.misc`:
ascii art, latex, mathjax, .... They should be moved into a common
package. I propose `sage.typeset`

URL: http://trac.sagemath.org/18357
Reported by: vbraun
Ticket author(s): Volker Braun, Vincent Delecroix
Reviewer(s): Vincent Delecroix, Volker Braun
  • Loading branch information
Release Manager authored and vbraun committed May 31, 2015
2 parents 8531803 + a6cf84f commit d619eb9
Show file tree
Hide file tree
Showing 44 changed files with 2,391 additions and 1,174 deletions.
18 changes: 17 additions & 1 deletion src/doc/common/conf.py
Expand Up @@ -369,7 +369,7 @@ def add(subdoc=''):
\DeclareUnicodeCharacter{2208}{\in}
\DeclareUnicodeCharacter{2209}{\notin}
\DeclareUnicodeCharacter{2202}{\partial}
\DeclareUnicodeCharacter{222B}{\int}
\DeclareUnicodeCharacter{222B}{\ensuremath{\int}}
\DeclareUnicodeCharacter{2148}{\id}
\DeclareUnicodeCharacter{2248}{\approx}
\DeclareUnicodeCharacter{2260}{\neq}
Expand Down Expand Up @@ -399,6 +399,22 @@ def add(subdoc=''):
\DeclareUnicodeCharacter{23A5}{\sageMexSymbol{"37}} % bracketrightex
\DeclareUnicodeCharacter{23A6}{\sageMexSymbol{"35}} % bracketrightbt
\DeclareUnicodeCharacter{23A7}{\sageMexSymbol{"38}} % curly brace left top
\DeclareUnicodeCharacter{23A8}{\sageMexSymbol{"3C}} % curly brace left middle
\DeclareUnicodeCharacter{23A9}{\sageMexSymbol{"3A}} % curly brace left bottom
\DeclareUnicodeCharacter{23AA}{\sageMexSymbol{"3E}} % curly brace extension
\DeclareUnicodeCharacter{23AB}{\sageMexSymbol{"39}} % curly brace right top
\DeclareUnicodeCharacter{23AC}{\sageMexSymbol{"3D}} % curly brace right middle
\DeclareUnicodeCharacter{23AD}{\sageMexSymbol{"3B}} % curly brace right bottom
\DeclareUnicodeCharacter{23B0}{\{} % 2-line curly brace left top half (not in cmex)
\DeclareUnicodeCharacter{23B1}{\}} % 2-line curly brace right top half (not in cmex)
\DeclareUnicodeCharacter{2320}{\ensuremath{\int}} % top half integral
\DeclareUnicodeCharacter{2321}{\ensuremath{\int}} % bottom half integral
\DeclareUnicodeCharacter{23AE}{\ensuremath{\|}} % integral extenison
\DeclareUnicodeCharacter{2571}{/} % Box drawings light diagonal upper right to lower left
\let\textLaTeX\LaTeX
\renewcommand*{\LaTeX}{\hbox{\textLaTeX}}
"""
Expand Down
6 changes: 5 additions & 1 deletion src/doc/en/reference/misc/index.rst
Expand Up @@ -180,7 +180,11 @@ Formatted Output
.. toctree::
:maxdepth: 1

sage/misc/ascii_art
sage/typeset/symbols
sage/typeset/character_art
sage/typeset/character_art_factory
sage/typeset/ascii_art
sage/typeset/unicode_art
sage/misc/sage_input
sage/misc/table

Expand Down
1 change: 1 addition & 0 deletions src/sage/all.py
Expand Up @@ -82,6 +82,7 @@

import sage.misc.lazy_import
from sage.misc.all import * # takes a while
from sage.typeset.all import *
from sage.repl.all import *

from sage.misc.sh import sh
Expand Down
4 changes: 2 additions & 2 deletions src/sage/combinat/abstract_tree.py
Expand Up @@ -949,10 +949,10 @@ def _ascii_art_(self):
node_to_str = lambda t: str(t.label()) if hasattr(t, "label") else "o"

if self.is_empty():
from sage.misc.ascii_art import empty_ascii_art
from sage.typeset.ascii_art import empty_ascii_art
return empty_ascii_art

from sage.misc.ascii_art import AsciiArt
from sage.typeset.ascii_art import AsciiArt
if len(self) == 0:
t_repr = AsciiArt( [node_to_str(self)] )
t_repr._root = 1
Expand Down
26 changes: 12 additions & 14 deletions src/sage/combinat/binary_tree.py
Expand Up @@ -376,10 +376,10 @@ def _ascii_art_( self ):
node_to_str = lambda bt: str(bt.label()) if hasattr(bt, "label") else "o"

if self.is_empty():
from sage.misc.ascii_art import empty_ascii_art
from sage.typeset.ascii_art import empty_ascii_art
return empty_ascii_art

from sage.misc.ascii_art import AsciiArt
from sage.typeset.ascii_art import AsciiArt
if self[0].is_empty() and self[1].is_empty():
bt_repr = AsciiArt( [node_to_str(self)] )
bt_repr._root = 1
Expand Down Expand Up @@ -1507,20 +1507,18 @@ def in_order_traversal_iter(self):
[ / \ ]
[ o o ]
sage: ascii_art(list(b.in_order_traversal_iter()))
[ ]
[ , o, , _o_ o o o ]
[ , o, , _o_ , , o, , o , , o, ]
[ / \ / \ ]
[ o o o o ]
[ / \ ]
[ o o, , , , , , , ]
[ o o ]
sage: ascii_art(filter(lambda node: node.label() is not None,
....: b.canonical_labelling().in_order_traversal_iter()))
[ ]
[ 1, _2_ 3 4 5 ]
[ 1, _2_ , 3, 4 , 5 ]
[ / \ / \ ]
[ 1 4 3 5 ]
[ / \ ]
[ 3 5, , , ]
[ 3 5 ]
sage: list(BinaryTree(None).in_order_traversal_iter())
[.]
Expand Down Expand Up @@ -2413,11 +2411,11 @@ def over(self, bt):
sage: b1 = BinaryTree([[],[[],[]]])
sage: b2 = BinaryTree([[None, []],[]])
sage: ascii_art((b1, b2, b1/b2))
( _o_ _o_ _o_ )
( _o_ , _o_ , _o_ )
( / \ / \ / \ )
( o o o o o o_ )
( / \ \ / \ )
( o o, o , o o )
( o o o o o )
( \ )
( _o_ )
( / \ )
Expand Down Expand Up @@ -2509,9 +2507,9 @@ def under(self, bt):
sage: b1 = BinaryTree([[],[]])
sage: b2 = BinaryTree([None,[]])
sage: ascii_art((b1, b2, b1 \ b2))
( o o _o_ )
( o , o , _o_ )
( / \ \ / \ )
( o o, o, o o )
( o o o o o )
( / \ )
( o o )
Expand Down Expand Up @@ -2771,11 +2769,11 @@ def is_full(self):
sage: BinaryTree([[[[],[]],[[],[]]], []]).is_full()
True
sage: ascii_art(filter(lambda bt: bt.is_full(), BinaryTrees(5)))
[ _o_ _o_ ]
[ _o_ , _o_ ]
[ / \ / \ ]
[ o o o o ]
[ / \ / \ ]
[ o o, o o ]
[ o o o o ]
"""
if self.is_empty():
return True
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/composition.py
Expand Up @@ -160,7 +160,7 @@ def _ascii_art_(self):
[ # # ## # # ## ### ]
[ #, ##, #, ###, #, ##, #, #### ]
"""
from sage.misc.ascii_art import ascii_art
from sage.typeset.ascii_art import ascii_art
return ascii_art(self.to_skew_partition())

def __setstate__(self, state):
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/crystals/tensor_product.py
Expand Up @@ -893,7 +893,7 @@ def _ascii_art_(self):
3 3 3 2
-4 -4 -4
"""
from sage.misc.ascii_art import ascii_art, AsciiArt
from sage.typeset.ascii_art import ascii_art, AsciiArt
s = ascii_art(self[0])
s._baseline = s._h // 2
ret = s
Expand Down
34 changes: 29 additions & 5 deletions src/sage/combinat/dyck_word.py
Expand Up @@ -606,14 +606,28 @@ def _ascii_art_(self):
[ /\ /\ /\/\ / \ ]
[ /\/\/\, /\/ \, / \/\, / \, / \ ]
"""
from sage.misc.ascii_art import AsciiArt
from sage.typeset.ascii_art import AsciiArt
rep = self.parent().global_options['ascii_art']
if rep == "path":
ret = self.to_path_string()
elif rep == "pretty_output":
ret = self._repr_lattice()
return AsciiArt(ret.splitlines(), baseline=0)

def _unicode_art_(self):
r"""
Return an unicode art representation of this Dyck word.
EXAMPLES::
sage: unicode_art(list(DyckWords(3)))
⎡ ╱╲ ⎤
⎢ ╱╲ ╱╲ ╱╲╱╲ ╱ ╲ ⎥
⎣ ╱╲╱╲╱╲, ╱╲╱ ╲, ╱ ╲╱╲, ╱ ╲, ╱ ╲ ⎦
"""
from sage.typeset.unicode_art import UnicodeArt
return UnicodeArt(self.to_path_string(unicode=True).splitlines())

def __str__(self):
r"""
Return a string consisting of matched parentheses corresponding to
Expand All @@ -631,7 +645,7 @@ def __str__(self):
else:
return "".join(map(replace_symbols, [x for x in self]))

def to_path_string(self):
def to_path_string(self, unicode=False):
r"""
A path representation of the Dyck word consisting of steps
``/`` and ``\`` .
Expand All @@ -648,15 +662,25 @@ def to_path_string(self):
/\/ \/\/\
/ \
"""
res = [([" "]*len(self)) for _ in range(self.height())]
if unicode:
import unicodedata
space = u' '
up = unicodedata.lookup('BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT')
down = unicodedata.lookup('BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT')
else:
space = ' '
up = '/'
down = '\\'

res = [([space]*len(self)) for _ in range(self.height())]
h = 1
for i, p in enumerate(self):
if p == open_symbol:
res[-h][i] = "/"
res[-h][i] = up
h += 1
else:
h -= 1
res[-h][i] = "\\"
res[-h][i] = down
return "\n".join("".join(l) for l in res)

def pretty_print(self, type=None, labelling=None, underpath=True):
Expand Down
4 changes: 2 additions & 2 deletions src/sage/combinat/free_module.py
Expand Up @@ -29,7 +29,7 @@
from sage.categories.all import Category, Sets, ModulesWithBasis
from sage.combinat.dict_addition import dict_addition, dict_linear_combination
from sage.sets.family import Family
from sage.misc.ascii_art import AsciiArt, empty_ascii_art
from sage.typeset.ascii_art import AsciiArt, empty_ascii_art

# TODO: move the content of this class to CombinatorialFreeModule.Element and ModulesWithBasis.Element
class CombinatorialFreeModuleElement(Element):
Expand Down Expand Up @@ -1328,7 +1328,7 @@ def _ascii_art_term(self, m):
sage: ascii_art(R.one()) # indirect doctest
1
"""
from sage.misc.ascii_art import AsciiArt
from sage.typeset.ascii_art import AsciiArt
try:
if m == self.one_basis():
return AsciiArt(["1"])
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/partition.py
Expand Up @@ -729,7 +729,7 @@ def _ascii_art_(self):
[ **** *** * ** * * ]
[ *****, * , ** , * , * , * , * ]
"""
from sage.misc.ascii_art import AsciiArt
from sage.typeset.ascii_art import AsciiArt
return AsciiArt(self._repr_diagram().splitlines(), baseline=0)

def _repr_list(self):
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/rigged_configurations/kr_tableaux.py
Expand Up @@ -1083,7 +1083,7 @@ def _ascii_art_(self):
1 3
2 4
"""
from sage.misc.ascii_art import AsciiArt
from sage.typeset.ascii_art import AsciiArt
return AsciiArt(self._repr_diagram().splitlines())

def to_kirillov_reshetikhin_crystal(self):
Expand Down
Expand Up @@ -448,7 +448,7 @@ def _ascii_art_(self):
baseline = lambda s: 0
else:
baseline = lambda s: len(s)
from sage.misc.ascii_art import AsciiArt
from sage.typeset.ascii_art import AsciiArt
s = repr(self[0]).splitlines()
ret = AsciiArt(s, baseline=baseline(s))
for tableau in self[1:]:
Expand Down
39 changes: 17 additions & 22 deletions src/sage/combinat/shuffle.py
Expand Up @@ -154,16 +154,15 @@ def _ascii_art_(self):
sage: ascii_art(SetShuffleProduct([[BinaryTree()], [BinaryTree([]), BinaryTree([[],[]])]],
....: [[1,4]]))
Set shuffle product of:
[ [ ] ]
[ [ o, o ] ]
[ [ / \ ] ] [ [ ] ]
[ [ / \ ] ]
[ [ ], [ o o ] ] and [ [ 1, 4 ] ]
"""
from sage.misc.ascii_art import ascii_art, ascii_art_list
from sage.typeset.ascii_art import ascii_art
return ascii_art("Set shuffle product of:") * \
(ascii_art_list(self._l1) + ascii_art(" and ") +
ascii_art_list(self._l2))
(ascii_art(self._l1) + ascii_art(" and ") +
ascii_art(self._l2))

def __iter__(self):
"""
Expand Down Expand Up @@ -292,22 +291,21 @@ def _ascii_art_(self):
sage: from sage.combinat.shuffle import ShuffleProduct
sage: ascii_art(ShuffleProduct([1,2,3],[4,5]))
Shuffle product of:
[ ] [ ]
[ 1, 2, 3 ] and [ 4, 5 ]
sage: B = BinaryTree
sage: ascii_art(ShuffleProduct([B([]), B([[],[]])],
....: [B([[[],[]],[[],None]])]))
Shuffle product of:
[ __o__ ]
[ ] [ / \ ]
[ / \ ]
[ o, o ] [ o o ]
[ / \ ] [ / \ / ]
[ o o ] and [ o o o ]
"""
from sage.misc.ascii_art import ascii_art, ascii_art_list
from sage.typeset.ascii_art import ascii_art
return ascii_art("Shuffle product of:") * \
(ascii_art_list(self._l1) + ascii_art(" and ") +
ascii_art_list(self._l2))
(ascii_art(self._l1) + ascii_art(" and ") +
ascii_art(self._l2))

def __iter__(self):
r"""
Expand All @@ -324,20 +322,17 @@ def __iter__(self):
sage: B = BinaryTree
sage: ascii_art(list(ShuffleProduct([B([]), B([[],[]])],
....: [B([[[],[]],[[],None]])])))
[ [ ] [
[ [ o, o __o__ ] [ __o__ o o ] [ o, __o__ o
[ [ / \ / \ ] [ / \ / \ ] [ / \ / \
[ [ o o, o o ] [ o o o o ] [ o o o o
[ [ o, o , __o__ ] [ __o__ , o, o ] [ o, __o__ ,
[ [ / \ / \ ] [ / \ / \ ] [ / \
[ [ o o o o ] [ o o o o ] [ o o
[ [ / \ / ] [ / \ / ] [ / \ /
[ [ o o o ], [ o o o , , ], [ o o o ,
[ [ o o o ], [ o o o ], [ o o o
<BLANKLINE>
] ]
] ]
] ]
] ]
] ]
] ]
o ] ]
/ \ ] ]
o o ] ]
] ]
] ]
"""

############ Gray code #############
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/skew_partition.py
Expand Up @@ -500,7 +500,7 @@ def _ascii_art_(self):
[ ###, ##, ##, #, #, #, #, #, # ]
sage: SkewPartitions.global_options.reset()
"""
from sage.misc.ascii_art import AsciiArt
from sage.typeset.ascii_art import AsciiArt
return AsciiArt(self.diagram().splitlines())

def inner(self):
Expand Down
2 changes: 1 addition & 1 deletion src/sage/combinat/skew_tableau.py
Expand Up @@ -289,7 +289,7 @@ def _ascii_art_(self):
[ 1 3 1 2 ]
[ 2 , 3 ]
"""
from sage.misc.ascii_art import AsciiArt
from sage.typeset.ascii_art import AsciiArt
return AsciiArt(self._repr_diagram().splitlines())

def _latex_(self):
Expand Down

0 comments on commit d619eb9

Please sign in to comment.