Skip to content

Commit 633ae18

Browse files
committed
Add json formatter
Which is used right now only by graphics3d
1 parent 5b85f11 commit 633ae18

3 files changed

Lines changed: 125 additions & 74 deletions

File tree

mathics/builtin/drawing/graphics3d.py

Lines changed: 4 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,10 @@ def boxes_to_mathml(self, leaves=None, **options):
641641

642642
elements._apply_boxscaling(boxscale)
643643

644-
json_repr = elements.to_json()
644+
# FIXME: json is the only thing we can convert MathML into.
645+
# Handle other graphics formats.
646+
format_fn = lookup_method(elements, "json")
647+
json_repr = format_fn(elements, **options)
645648

646649
xmin, xmax, ymin, ymax, zmin, zmax, boxscale = calc_dimensions()
647650

@@ -788,12 +791,6 @@ def _apply_boxscaling(self, boxscale):
788791
for element in self.elements:
789792
element._apply_boxscaling(boxscale)
790793

791-
def to_json(self):
792-
result = []
793-
for element in self.elements:
794-
result.extend(element.to_json())
795-
return result
796-
797794
def get_style_class(self):
798795
return Style3D
799796

@@ -805,25 +802,6 @@ def init(self, *args, **kwargs):
805802
def process_option(self, name, value):
806803
super(Point3DBox, self).process_option(name, value)
807804

808-
def to_json(self):
809-
# TODO: account for point size
810-
data = []
811-
812-
# Tempoary bug fix: default Point color should be black not white
813-
face_color = self.face_color
814-
if list(face_color.to_rgba()[:3]) == [1, 1, 1]:
815-
face_color = RGBColor(components=(0, 0, 0, face_color.to_rgba()[3]))
816-
817-
for line in self.lines:
818-
data.append(
819-
{
820-
"type": "point",
821-
"coords": [coords.pos() for coords in line],
822-
"color": face_color.to_rgba(),
823-
}
824-
)
825-
return data
826-
827805
def extent(self):
828806
result = []
829807
for line in self.lines:
@@ -845,19 +823,6 @@ def init(self, *args, **kwargs):
845823
def process_option(self, name, value):
846824
super(Line3DBox, self).process_option(name, value)
847825

848-
def to_json(self):
849-
# TODO: account for line widths and style
850-
data = []
851-
for line in self.lines:
852-
data.append(
853-
{
854-
"type": "line",
855-
"coords": [coords.pos() for coords in line],
856-
"color": self.edge_color.to_rgba(),
857-
}
858-
)
859-
return data
860-
861826
def extent(self):
862827
result = []
863828
for line in self.lines:
@@ -884,27 +849,6 @@ def process_option(self, name, value):
884849
else:
885850
super(Polygon3DBox, self).process_option(name, value)
886851

887-
def to_json(self):
888-
# TODO: account for line widths and style
889-
if self.vertex_colors is None:
890-
face_color = self.face_color
891-
else:
892-
face_color = None
893-
894-
if face_color is not None:
895-
face_color = face_color.to_js()
896-
897-
data = []
898-
for line in self.lines:
899-
data.append(
900-
{
901-
"type": "polygon",
902-
"coords": [coords.pos() for coords in line],
903-
"faceColor": face_color,
904-
}
905-
)
906-
return data
907-
908852
def extent(self):
909853
result = []
910854
for line in self.lines:
@@ -1098,19 +1042,6 @@ def init(self, graphics, style, item):
10981042
self.points = [Coords3D(graphics, pos=point) for point in points]
10991043
self.radius = item.leaves[1].to_python()
11001044

1101-
def to_json(self):
1102-
face_color = self.face_color
1103-
if face_color is not None:
1104-
face_color = face_color.to_js()
1105-
return [
1106-
{
1107-
"type": "sphere",
1108-
"coords": [coords.pos() for coords in self.points],
1109-
"radius": self.radius,
1110-
"faceColor": face_color,
1111-
}
1112-
]
1113-
11141045
def extent(self):
11151046
result = []
11161047
result.extend(

mathics/core/definitions.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,11 @@ def __init__(
125125
self.builtin.update(self.user)
126126
self.user = {}
127127
self.clear_cache()
128-
import mathics.formatter.svg # noqa
128+
129+
# FIXME load dynamically as we do other things
129130
import mathics.formatter.asy # noqa
131+
import mathics.formatter.json # noqa
132+
import mathics.formatter.svg # noqa
130133

131134
def load_pymathics_module(self, module, remove_on_quit=True):
132135
"""

mathics/formatter/json.py

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
Format a Mathics object as json
4+
"""
5+
6+
from mathics.builtin.graphics import RGBColor
7+
8+
from mathics.builtin.drawing.graphics3d import (
9+
Graphics3DElements,
10+
Line3DBox,
11+
Point3DBox,
12+
Polygon3DBox,
13+
Sphere3DBox,
14+
)
15+
16+
from mathics.core.formatter import lookup_method, add_conversion_fn
17+
18+
19+
def graphics_3D_elements(self, **options):
20+
result = []
21+
for element in self.elements:
22+
format_fn = lookup_method(element, "json")
23+
if format_fn is None:
24+
result += element.to_json()
25+
else:
26+
result += format_fn(element)
27+
28+
# print("### json Graphics3DElements", result)
29+
return result
30+
31+
32+
add_conversion_fn(Graphics3DElements, graphics_3D_elements)
33+
34+
35+
def line_3d_box(self):
36+
# TODO: account for line widths and style
37+
data = []
38+
for line in self.lines:
39+
data.append(
40+
{
41+
"type": "line",
42+
"coords": [coords.pos() for coords in line],
43+
"color": self.edge_color.to_rgba(),
44+
}
45+
)
46+
# print("### json Line3DBox", data)
47+
return data
48+
49+
50+
add_conversion_fn(Line3DBox, line_3d_box)
51+
52+
53+
def point_3d_box(self):
54+
# TODO: account for point size
55+
data = []
56+
57+
# Tempoary bug fix: default Point color should be black not white
58+
face_color = self.face_color
59+
if list(face_color.to_rgba()[:3]) == [1, 1, 1]:
60+
face_color = RGBColor(components=(0, 0, 0, face_color.to_rgba()[3]))
61+
62+
for line in self.lines:
63+
data.append(
64+
{
65+
"type": "point",
66+
"coords": [coords.pos() for coords in line],
67+
"color": face_color.to_rgba(),
68+
}
69+
)
70+
# print("### json Point3DBox", data)
71+
return data
72+
73+
74+
add_conversion_fn(Point3DBox, point_3d_box)
75+
76+
77+
def polygon_3d_box(self):
78+
# TODO: account for line widths and style
79+
if self.vertex_colors is None:
80+
face_color = self.face_color
81+
else:
82+
face_color = None
83+
84+
if face_color is not None:
85+
face_color = face_color.to_js()
86+
87+
data = []
88+
for line in self.lines:
89+
data.append(
90+
{
91+
"type": "polygon",
92+
"coords": [coords.pos() for coords in line],
93+
"faceColor": face_color,
94+
}
95+
)
96+
# print("### json Polygon3DBox", data)
97+
return data
98+
99+
100+
add_conversion_fn(Polygon3DBox, polygon_3d_box)
101+
102+
103+
def sphere_3d_box(self):
104+
face_color = self.face_color
105+
if face_color is not None:
106+
face_color = face_color.to_js()
107+
return [
108+
{
109+
"type": "sphere",
110+
"coords": [coords.pos() for coords in self.points],
111+
"radius": self.radius,
112+
"faceColor": face_color,
113+
}
114+
]
115+
116+
117+
add_conversion_fn(Sphere3DBox, sphere_3d_box)

0 commit comments

Comments
 (0)