Opened 14 months ago

Closed 3 months ago

Unicode operators for sage.manifolds

Reported by: Owned by: mkoeppe major sage-9.4 user interface egourgoulhon, tscrim, gh-mwageringel, chapoton Eric Gourgoulhon Matthias Koeppe N/A f2ae50e f2ae50e68687b59af27e35a4ec02b0f667ea828c

Replacing

• /\ by ∧ (U+2227)
• * by ⊗ (U+2297) for tensor products
• --> by → (U+2192), |--> by ↦ (U+21A6)
• d/dx by ∂/∂x, etc. (U+2202)
• R (real field) by ℝ (U+211D)
• C (complex field) by ℂ (U+2102)

Some references:

With the code introduced in this ticket, we have

sage: M = Manifold(2, 'M')
sage: X.<x,y> = M.chart()
sage: M.identity_map().display()
Id_M: M → M
(x, y) ↦ (x, y)
sage: M.zero_scalar_field().display()
zero: M → ℝ
(x, y) ↦ 0
sage: v = M.vector_field(-y, x, name='v')
sage: v.display()
v = -y ∂/∂x + x ∂/∂y
sage: X.frame()
Coordinate frame (M, (∂/∂x,∂/∂y))
sage: v.wedge(X.frame()[0]).display()
v∧∂/∂x = -x ∂/∂x∧∂/∂y
sage: f = M.scalar_field(x^2 + y^2, name='f')
sage: f.display()
f: M → ℝ
(x, y) ↦ x^2 + y^2
sage: diff(f).display()
df = 2*x dx + 2*y dy
sage: (v*diff(f)).display()
v⊗df = -2*x*y ∂/∂x⊗dx - 2*y^2 ∂/∂x⊗dy + 2*x^2 ∂/∂y⊗dx + 2*x*y ∂/∂y⊗dy


comment:1 Changed 14 months ago by egourgoulhon

Sounds a good idea!

comment:2 Changed 12 months ago by mkoeppe

• Milestone changed from sage-9.2 to sage-9.3

comment:3 Changed 10 months ago by mkoeppe

• Cc chapoton added

comment:4 follow-up: ↓ 5 Changed 9 months ago by gh-mjungmath

That's a really nice idea! Is it also possible to entail the first two characters as operators in Python code?

comment:5 in reply to: ↑ 4 ; follow-up: ↓ 6 Changed 9 months ago by gh-mwageringel

Is it also possible to entail the first two characters as operators in Python code?

That is not possible in Python, but it could be added to the Sage preparser, as has been done for the backslash operator. Some people at sd109 voiced an interest in such custom unicode operators.

There is also a decorator that turns functions into infix operators which works similarly to the backslash operator, but, as unicode operators are not valid function names, that does not really help.

comment:6 in reply to: ↑ 5 ; follow-up: ↓ 7 Changed 9 months ago by gh-mjungmath

Is it also possible to entail the first two characters as operators in Python code?

That is not possible in Python, but it could be added to the Sage preparser, as has been done for the backslash operator. Some people at sd109 voiced an interest in such custom unicode operators.

I'd like that very much, too. Is the preparser also capable of something like

type "\otimes" -> press TAB -> unicode character pops up

similarly to Greek letters in Py3 right now?

comment:7 in reply to: ↑ 6 ; follow-up: ↓ 53 Changed 9 months ago by gh-mwageringel

Is the preparser also capable of something like

type "\otimes" -> press TAB -> unicode character pops up

similarly to Greek letters in Py3 right now?

That is an IPython feature, which does not seem to be implemented for operators like \otimes. The preparser is not capable of this.

comment:8 Changed 8 months ago by mkoeppe

• Milestone changed from sage-9.3 to sage-9.4

Setting new milestone based on a cursory review of ticket status, priority, and last modification date.

comment:9 Changed 4 months ago by egourgoulhon

• Description modified (diff)

comment:10 Changed 4 months ago by egourgoulhon

I gave it a try, by changing line 736 of src/sage/tensor/modules/free_module_tensor.py:

-                basis_term_txt = "*".join(bases_txt)
+                basis_term_txt = "\u2297".join(bases_txt)


and changing doctests accordingly. Everything seems OK with doctests and the html documentation. However, generating the pdf documentation by

sage -docbuild reference/tensor_free_modules pdf


failed, with the error:

! Package inputenc Error: Unicode character ⊗ (U+2297)
(inputenc)                not set up for use with LaTeX.


I had to add the following line in src/sage/docs/conf.py (after line 407):

    \DeclareUnicodeCharacter{2297}{\ensuremath{\otimes}}


to make the pdf documentation build without any error. The pdf output is fine (the tensor product operator is correctly displayed). However, before to proceed, I would like to know if this the correct way to fix the pdf doc building...

comment:11 follow-up: ↓ 12 Changed 4 months ago by chapoton

There is already a tensor product somewhere, with no pdf problem:

sage: A=algebras.FreeDendriform(QQ,'a')
sage: %display unicode_art
sage: a=A.an_element()
sage: A.coproduct(a)
1 ⨂ B  + 2*1 ⨂ B    + 2*1 ⨂ B    + B  ⨂ 1 + 4*B  ⨂ B  + 2*B    ⨂ 1 + 2*B    ⨂ 1
a          a              a    a          a    a      a              a
╲            ╱                             ╲            ╱
a          a                               a          a


*EDIT*

git grep "⨂" src/sage
src/sage/categories/signed_tensor.py:    unicode_symbol = " ⨂ "
src/sage/categories/tensor.py:    unicode_symbol = " ⨂ "
src/sage/combinat/free_module.py:                R    ⨂ R


*EDIT* : But in fact, it does not appear in pdf doc, because it's only in hidden methods.

Last edited 4 months ago by chapoton (previous) (diff)

comment:12 in reply to: ↑ 11 ; follow-up: ↓ 17 Changed 4 months ago by egourgoulhon

There is already a tensor product somewhere, with no pdf problem:

*EDIT* : But in fact, it does not appear in pdf doc, because it's only in hidden methods.

Thank you for pointing out the existence of ⨂ in src/sage/categories/tensor.py. It is U+2A02 (unicode name: n-ary circled times operator), while U+2297 is for ⊗ (unicode name: circled times). In terms of readability, U+2A02 is much better than U+2297, so we should definitely use U+2A02.

comment:13 Changed 4 months ago by egourgoulhon

With U+2A02, I had to perform the following change to src/sage/docs/conf.py to get the pdf doc built:

-    \DeclareUnicodeCharacter{2A02}{\otimes}
+    \DeclareUnicodeCharacter{2A02}{\ensuremath{\otimes}}


The output pdf looks OK.

comment:14 Changed 4 months ago by egourgoulhon

• Description modified (diff)

comment:15 Changed 4 months ago by egourgoulhon

• Description modified (diff)

comment:16 follow-up: ↓ 19 Changed 4 months ago by mkoeppe

You may want to make this change on top of the branch of #31880, which touches the same file, to avoid merge conflicts

comment:17 in reply to: ↑ 12 ; follow-up: ↓ 18 Changed 4 months ago by gh-mwageringel

In terms of readability, U+2A02 is much better than U+2297, so we should definitely use U+2A02.

I am in favor of U+2297, as it is used as a binary operator. The n-ary operator would correspond to \bigotimes in tex instead. At least with the Dejavu Sans Mono font, the binary operator looks good to me, whereas the n-ary operator U+2A02 is too wide for a monospaced font (which could lead to misaligned unicode art).

However, before to proceed, I would like to know if this the correct way to fix the pdf doc building...

Yes, this is the correct way to add support for unicode characters to the pdf documentation.

Last edited 4 months ago by gh-mwageringel (previous) (diff)

comment:18 in reply to: ↑ 17 Changed 4 months ago by egourgoulhon

In terms of readability, U+2A02 is much better than U+2297, so we should definitely use U+2A02.

I am in favor of U+2297, as it is used as a binary operator. The n-ary operator would correspond to \bigotimes in tex instead. At least with the Dejavu Sans Mono font, the binary operator looks good to me, whereas the n-ary operator U+2A02 is too wide for a monospaced font (which could lead to misaligned unicode art).

My initial preference for U+2A02 came from the appearance in Sage's console in the Ubuntu terminal (font: Monospace Regular 13):

• for U+2A02:
• for U+2297:

However, when cutting and pasting to gedit (font: Ubuntu Mono 13), we get:

As you said, U+2A02 appears too large. So, unless someone argues against it, I am going to revert to U+2297. It's also more natural since U+2297 is the standard symbol for tensor product as a binary operator, as your pointed out. Thanks for your advice!

However, before to proceed, I would like to know if this the correct way to fix the pdf doc building...

Yes, this is the correct way to add support for unicode characters to the pdf documentation.

comment:19 in reply to: ↑ 16 Changed 4 months ago by egourgoulhon

You may want to make this change on top of the branch of #31880, which touches the same file, to avoid merge conflicts

Thanks for the advice; however this ticket has no logical connection with #31880 and the merge conflict in src/sage/docs/conf.py will be a trivial one. Moreover, since I am touching almost all files in src/sage/manifolds and src/sage/tensor/modules, there will be merge conflicts with the next beta anyway.

comment:20 Changed 4 months ago by egourgoulhon

• Authors set to Eric Gourgoulhon
• Branch set to public/manifolds/unicode_art
• Commit set to f6bcc9d7e94ee770679c58d9e06ed0ed6f29f94b

Here is a preliminary version, which implements ⊗ and ∧. There remains to implement →, ↦ and ∂ (I shall do it tomorrow).

New commits:

 ​33aec3c Use unicode symbol 2A02 for tensor product on finite rank free modules ​f8dac45 Use Unicode symbol 2227 for exterior product on finite rank free modules ​4763886 Used Unicode symbol 2297 for tensor product on finite rank free modules ​8fb91b4 WIP: Unicode symbols for exterior and tensor products of tensor fields ​f6bcc9d Unicode symbols for exterior and tensor products of tensor fields

comment:21 follow-ups: ↓ 22 ↓ 23 Changed 4 months ago by gh-mjungmath

Perhaps it might be a good idea to refactor the code in such a way that the symbols can be changed easily? Something like global variables such as wedge_symbol?

This might have the following benefits:

• Unification throughout Sage, i.e. tensor products are used not only for free modules.
• It is easier to change if we are not quite satisfied with the result at a later point.

comment:22 in reply to: ↑ 21 Changed 4 months ago by tscrim

Perhaps it might be a good idea to refactor the code in such a way that the symbols can be changed easily? Something like global variables such as wedge_symbol?

+1

comment:23 in reply to: ↑ 21 Changed 4 months ago by egourgoulhon

Perhaps it might be a good idea to refactor the code in such a way that the symbols can be changed easily? Something like global variables such as wedge_symbol?

I don't think it's worth to clutter Sage's global variables for such a thing. There aren't actually so many unicode options. For instance, for the tensor product of tensor fields, there are two of them: U+2297 and U+2A02 and the discussion in comment:17 and comment:18 reveals that U+2A02 is not appropriate. Moreover, it is quite easy to spot where the symbols are implemented in Sage's code: from src/sage,

git grep 'u2297'


yields

tensor/modules/free_module_tensor.py:                basis_term_txt = "\u2297".join(bases_txt)
tensor/modules/free_module_tensor.py:            result._name = format_mul_txt(self._name, '\u2297', other._name)


By the way, this is the reason why I used basis_term_txt = "\u2297".join(bases_txt) instead of basis_term_txt = "⊗".join(bases_txt), which would have been equivalent in terms of output.

In any case, I would vote for the discussion about global variables to be deferred to another ticket. To minimize merge conflicts, it would be helpful to have the current ticket merged not too late.

comment:24 follow-up: ↓ 35 Changed 4 months ago by slelievre

Maybe add a comment? And use single quotes both times?

-                basis_term_txt = "\u2297".join(bases_txt)
+                # Unicode character '\u2297' is '⊗'; see ticket #30473
+                basis_term_txt = '\u2297'.join(bases_txt)

+            # Unicode character '\u2297' is '⊗'; see ticket #30473
result._name = format_mul_txt(self._name, '\u2297', other._name)


comment:25 follow-up: ↓ 31 Changed 4 months ago by gh-mjungmath

I just see that all three display methods basically contain the same code. I think some common parts should be outsourced for example in sage.tensor.format_utilities.

This might also be useful in view of mixed forms, which have their own display method as well.

comment:26 follow-up: ↓ 27 Changed 4 months ago by gh-mjungmath

@Eric: Could you change the wedge symbol in mixed_form.py as well please?

comment:27 in reply to: ↑ 26 ; follow-up: ↓ 29 Changed 4 months ago by egourgoulhon

@Eric: Could you change the wedge symbol in mixed_form.py as well please?

comment:28 follow-up: ↓ 30 Changed 4 months ago by tscrim

I wasn't thinking of adding this to the global namespace, but having a file where people can import the symbols to use in their string outputs.

comment:29 in reply to: ↑ 27 Changed 4 months ago by gh-mjungmath

@Eric: Could you change the wedge symbol in mixed_form.py as well please?

Ah perfect. Sorry, haven't noticed. Thanks! :)

comment:30 in reply to: ↑ 28 ; follow-up: ↓ 38 Changed 4 months ago by egourgoulhon

I wasn't thinking of adding this to the global namespace, but having a file where people can import the symbols to use in their string outputs.

Yes, that's what I understood, but IMHO this implies some discussion:

• where to put this file?
• shall we homogenize between various parts of Sage? (for instance as pointed out in comment:11, tensor products of modules use U+2A02 (\bigotimes), while here, we are using here U+2297 (\otimes) for tensor products of elements)
• how to name the Python variables? (I would suggest a naming convention from the LaTeX names of the symbols, e.g. something like unicode_otimes, unicode_mapsto, etc.)
• how to articulate this file with src/sage/docs/conf.py? (i.e. ensure that each time a new variable is added to this file, it will be taken into account in conf.py)

For this reason, I would prefer this to be done in another ticket.

comment:31 in reply to: ↑ 25 Changed 4 months ago by egourgoulhon

I just see that all three display methods basically contain the same code. I think some common parts should be outsourced for example in sage.tensor.format_utilities.

Yes certainly, but in another ticket.

comment:32 Changed 4 months ago by git

• Commit changed from f6bcc9d7e94ee770679c58d9e06ed0ed6f29f94b to afa0e72feba703b762508c907795a6d787ac5b00

Branch pushed to git repo; I updated commit sha1. New commits:

 ​7e91c14 #30473: Add some comments about unicode symbols ​9091e7d Unicode symbol 21A6 for text display of continuous maps and chart functions ​db2f163 Unicode symbol 2192 for text display of continuous maps and scalar fields ​afa0e72 Unicode symbols 211D and 2102 for text display of the codomains of scalar fields

comment:33 Changed 4 months ago by egourgoulhon

Here is a new provisory version, implementing →, ↦, as well as ℝ and ℂ for the codomains of scalar fields on respectively real and complex manifolds.

There remains to implement ∂ for coordinate frames.

comment:34 Changed 4 months ago by egourgoulhon

• Description modified (diff)

comment:35 in reply to: ↑ 24 Changed 4 months ago by egourgoulhon

Maybe add a comment? And use single quotes both times?

-                basis_term_txt = "\u2297".join(bases_txt)
+                # Unicode character '\u2297' is '⊗'; see ticket #30473
+                basis_term_txt = '\u2297'.join(bases_txt)


Thanks for the suggestion. This is done in the latest version (comment:32).

comment:36 Changed 4 months ago by egourgoulhon

• Description modified (diff)

comment:37 Changed 4 months ago by git

• Commit changed from afa0e72feba703b762508c907795a6d787ac5b00 to 4e13ffa05615e91d6b266660481516c72c39d25e

Branch pushed to git repo; I updated commit sha1. New commits:

 ​4e13ffa Unicode symbols defined in new file src/sage/typeset/unicode_characters.py

comment:38 in reply to: ↑ 30 Changed 4 months ago by egourgoulhon

I wasn't thinking of adding this to the global namespace, but having a file where people can import the symbols to use in their string outputs.

Yes, that's what I understood, but IMHO this implies some discussion [...]

For this reason, I would prefer this to be done in another ticket.

Having slept on it, I've finally included this in the current ticket ;-)

I've put the file defining Python identifiers for Unicode characters in src/sage/typeset and named it unicode_characters.py, cf. https://git.sagemath.org/sage.git/tree/src/sage/typeset/unicode_characters.py?id=4e13ffa05615e91d6b266660481516c72c39d25e

I've also included it in the reference manual, in the section "Programming -> Utilities -> Formatted Output -> Unicode characters".

Regarding the last point of :comment:30, there is no (automatic) articulation with src/sage/docs/conf.py yet.

Last edited 4 months ago by egourgoulhon (previous) (diff)

comment:39 Changed 4 months ago by git

• Commit changed from 4e13ffa05615e91d6b266660481516c72c39d25e to da8893f5c68353345ba8a18a07d371705084a9e7

Branch pushed to git repo; I updated commit sha1. New commits:

 ​da8893f Use sage.typeset.unicode_characters in TensorProductFunctor and SignedTensorProductFunctor

comment:40 Changed 4 months ago by egourgoulhon

In the above commit, I used the new file unicode_characters.py to deal with the symbol ⨂ (bigotimes) pointed out in comment:11. Frédéric, Travis, do you agree?

comment:41 follow-up: ↓ 43 Changed 4 months ago by slelievre

Have you considered formatted strings instead of additions?

-    unicode_symbol = " " + unicode_bigotimes + " "
+    unicode_symbol = f" {unicode_bigotimes} "


comment:42 Changed 4 months ago by git

• Commit changed from da8893f5c68353345ba8a18a07d371705084a9e7 to 5167e6cfc4130eb88b78ddf9eb5e130c089f39f9

Branch pushed to git repo; I updated commit sha1. New commits:

 ​2a23cb5 Unicode symbol 2202 (partial) for the text display of coordinate frames ​5d096f1 f-string for unicode_symbol in TensorProductFunctor and SignedTensorProductFunctor ​76c2fd5 Use Unicode symbol for the Riemann sphere example ​5167e6c Use Unicode symbol for default text display of RealLine

comment:43 in reply to: ↑ 41 Changed 4 months ago by egourgoulhon

Have you considered formatted strings instead of additions?

-    unicode_symbol = " " + unicode_bigotimes + " "
+    unicode_symbol = f" {unicode_bigotimes} "


Thanks for the tip; this is done in the latest version.

comment:44 Changed 4 months ago by egourgoulhon

• Status changed from new to needs_review

I've added ∂/∂... for the vector fields of coordinate frames and ℝ for the real line. So I think this is ready for review now.

comment:45 follow-up: ↓ 46 Changed 4 months ago by gh-mwageringel

Shouldn't unicode output only be used if %display unicode_art is set? It is not set by default, which means that it would not be necessary to touch all the doctests in this ticket.

As unicode output requires the presence of suitable fonts, I think it might be best if it stays optional.

comment:46 in reply to: ↑ 45 ; follow-up: ↓ 48 Changed 4 months ago by mkoeppe

Shouldn't unicode output only be used if %display unicode_art is set? It is not set by default, which means that it would not be necessary to touch all the doctests in this ticket.

No, I don't think so. "Unicode art", in extension of "ASCII art", means to use multiline character art. Merely using non-ASCII characters does not make something unicode art.

comment:47 Changed 4 months ago by mkoeppe

• Summary changed from Unicode art for sage.manifolds to Unicode operators for sage.manifolds

(The title of the ticket should probably be changed.)

comment:48 in reply to: ↑ 46 ; follow-up: ↓ 50 Changed 4 months ago by gh-mwageringel

No, I don't think so. "Unicode art", in extension of "ASCII art", means to use multiline character art. Merely using non-ASCII characters does not make something unicode art.

Ok, thanks for clarifying.

comment:49 Changed 4 months ago by egourgoulhon

• Description modified (diff)

comment:50 in reply to: ↑ 48 Changed 4 months ago by egourgoulhon

No, I don't think so. "Unicode art", in extension of "ASCII art", means to use multiline character art. Merely using non-ASCII characters does not make something unicode art.

Ok, thanks for clarifying.

I've updated the ticket description to show the purpose of this ticket via some examples.

comment:51 Changed 4 months ago by egourgoulhon

• Description modified (diff)

comment:52 follow-up: ↓ 55 Changed 4 months ago by tscrim

I think in *TensorProductFunctor, we should use U+2297 -- i.e., unicode_otimes -- since it is a binary operator.

comment:53 in reply to: ↑ 7 Changed 4 months ago by nbruin

Is the preparser also capable of something like

type "\otimes" -> press TAB -> unicode character pops up

similarly to Greek letters in Py3 right now?

That is an IPython feature, which does not seem to be implemented for operators like \otimes. The preparser is not capable of this.

Th IPython feature could be hooked into. The relevant dictionaries are IPython.core.latex_symbols.latex_symbols and IPython.core.latex_symbols.reverse_latex_symbols. You could install new translations by updating those dictionaries. It would probably be worth trialing it a bit to see if there are unwanted side-effects (the dictionary may be used for other purposes -- the source mentions it's a list borrowed from Julia, with entries removed that do not yield valid Python identifiers)

comment:54 Changed 4 months ago by git

• Commit changed from 5167e6cfc4130eb88b78ddf9eb5e130c089f39f9 to 332410b486ea3e180c073042980947d820824674

Branch pushed to git repo; I updated commit sha1. New commits:

 ​332410b Use unicode_otimes in TensorProductFunctor and SignedTensorProductFunctor

comment:55 in reply to: ↑ 52 Changed 4 months ago by egourgoulhon

I think in *TensorProductFunctor, we should use U+2297 -- i.e., unicode_otimes -- since it is a binary operator.

Done in the latest commit. Incidently, note that this is doctested by only one test, in src/sage/combinat/free_module.py, and never shows up in the reference manual, as pointed out in comment:11.

comment:56 Changed 4 months ago by gh-mjungmath

What's wrong with the patchbot? I'm looking forward for a positive review due to #30272.

comment:57 Changed 4 months ago by slelievre

Some patchbots are stuck due to #29977.

comment:58 follow-up: ↓ 60 Changed 3 months ago by mkoeppe

• Status changed from needs_review to needs_work
sage -t --random-seed=0 src/sage/manifolds/differentiable/diff_map.py
**********************************************************************
File "src/sage/manifolds/differentiable/diff_map.py", line 933, in sage.manifolds.differentiable.diff_map.DiffMap.pullback
Failed example:
gM.display()
Expected:
(2*cos(t) + 2) dt*dt
Got:
(2*cos(t) + 2) dt⊗dt


comment:59 Changed 3 months ago by git

• Commit changed from 332410b486ea3e180c073042980947d820824674 to d87d09b7e101ac462c04372b2f8cd691cdb774a1

Branch pushed to git repo; I updated commit sha1. New commits:

 ​f5d15d2 Merge branch 'public/manifolds/unicode_art' of git://trac.sagemath.org/sage into Sage 9.4.beta4. ​d87d09b #30473: fix doctest error in DiffMap.pullback

comment:60 in reply to: ↑ 58 Changed 3 months ago by egourgoulhon

• Status changed from needs_work to needs_review

sage -t --random-seed=0 src/sage/manifolds/differentiable/diff_map.py
**********************************************************************
File "src/sage/manifolds/differentiable/diff_map.py", line 933, in sage.manifolds.differentiable.diff_map.DiffMap.pullback
Failed example:
gM.display()
Expected:
(2*cos(t) + 2) dt*dt
Got:
(2*cos(t) + 2) dt⊗dt


Thanks for pointing this out (this was due to the merge of #31904 in 9.4.beta4).

comment:61 follow-up: ↓ 62 Changed 3 months ago by mkoeppe

• Reviewers set to Matthias Koeppe
• Status changed from needs_review to positive_review

comment:62 in reply to: ↑ 61 Changed 3 months ago by egourgoulhon

Thank you for the review!

comment:63 follow-up: ↓ 65 Changed 3 months ago by vbraun

• Status changed from positive_review to needs_work

I'm getting a lot of test failures of the form

**********************************************************************
File "src/sage/calculus/functional.py", line 145, in sage.calculus.functional.derivative
Failed example:
derivative(a).display()
Expected:
da = 2 dx/\dy
Got:
da = 2 dx∧dy
**********************************************************************


can you please do a whole make ptestlong

comment:64 Changed 3 months ago by git

• Commit changed from d87d09b7e101ac462c04372b2f8cd691cdb774a1 to f2ae50e68687b59af27e35a4ec02b0f667ea828c

Branch pushed to git repo; I updated commit sha1. New commits:

 ​f2ae50e #30473: fix doctests outside sage/manifolds and sage/tensor/modules

comment:65 in reply to: ↑ 63 Changed 3 months ago by egourgoulhon

• Status changed from needs_work to needs_review

I'm getting a lot of test failures of the form [...] can you please do a whole make ptestlong

Thanks for pointing this out. This is fixed in the latest commit.

comment:66 Changed 3 months ago by mkoeppe

• Status changed from needs_review to positive_review

comment:67 Changed 3 months ago by vbraun

• Branch changed from public/manifolds/unicode_art to f2ae50e68687b59af27e35a4ec02b0f667ea828c
• Resolution set to fixed
• Status changed from positive_review to closed
Note: See TracTickets for help on using tickets.