Coverage for src/pycse/orgmode.py: 0.00%
121 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-23 16:23 -0400
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-23 16:23 -0400
1"""Provides classes to convert python data into org markup."""
3import IPython
4import tabulate
7class Heading:
8 """An orgmode headline."""
10 def __init__(self, title, level=1, tags=(), properties=None):
11 """Initialize a Heading."""
12 self.title = title
13 self.level = level
14 self.tags = tags
15 self.properties = properties
17 def _repr_org(self):
18 """Provide an org representation."""
19 s = "*" * self.level + " " + self.title
20 if self.tags:
21 s += f" :{':'.join(self.tags)}:"
22 if self.properties:
23 s += "\n:PROPERTIES:\n"
24 for key in self.properties:
25 s += f":{key}: {self.properties[key]}\n"
26 s += ":END:"
27 return s + "\n"
29 def _repr_html(self):
30 """HTML representation of a Heading."""
31 return f"<h{self.level}>{self.title}</h{self.level}>"
33 def _repr_mimebundle_(self, include, exclude, **kwargs):
34 """Mimebundle representation of a Heading.
36 repr_mimebundle should accept include, exclude and **kwargs.
37 """
38 data = {"text/html": self._repr_html(), "text/org": self._repr_org()}
39 if include:
40 data = {k: v for (k, v) in data.items() if k in include}
41 if exclude:
42 data = {k: v for (k, v) in data.items() if k not in exclude}
43 return data
46class Keyword:
47 """Keyword(key, value) -> #+key: value."""
49 def __init__(self, key, value):
50 """Initialize a Keyword."""
51 self.key = key
52 self.value = value
54 def _repr_org(self):
55 """Provide org representation."""
56 return f"#+{self.key}: {self.value}" + "\n"
58 def _repr_mimebundle_(self, include, exclude, **kwargs):
59 """Provide a mimebundle representation.
61 repr_mimebundle should accept include, exclude and **kwargs
62 """
63 data = {"text/org": self._repr_org()}
64 if include:
65 data = {k: v for (k, v) in data.items() if k in include}
66 if exclude:
67 data = {k: v for (k, v) in data.items() if k not in exclude}
68 return data
71class Comment:
72 """Comment(text) -> # text."""
74 def __init__(self, text):
75 """Initialize a comment."""
76 self.text = text
78 def _repr_org(self):
79 """Provide an org representation."""
80 return f"# {self.text}" + "\n"
82 def _repr_mimebundle_(self, include, exclude, **kwargs):
83 """Provide a mimebundle representation.
85 repr_mimebundle should accept include, exclude and **kwargs
86 """
87 data = {"text/org": self._repr_org()}
88 if include:
89 data = {k: v for (k, v) in data.items() if k in include}
90 if exclude:
91 data = {k: v for (k, v) in data.items() if k not in exclude}
92 return data
95class Org:
96 """Org(text) -> text."""
98 def __init__(self, text):
99 """Initialize an Org object."""
100 self.text = text
102 def _repr_org(self):
103 """Provide an org representation."""
104 return self.text + "\n"
106 def _repr_mimebundle_(self, include, exclude, **kwargs):
107 """Provide a mimebundle representation.
109 repr_mimebundle should accept include, exclude and **kwargs
110 """
111 data = {"text/org": self._repr_org()}
112 if include:
113 data = {k: v for (k, v) in data.items() if k in include}
114 if exclude:
115 data = {k: v for (k, v) in data.items() if k not in exclude}
116 return data
119class Figure:
120 """A Figure class for org.
122 It combines a filename, caption, name and attributes.
123 """
125 def __init__(self, fname, caption=None, name=None, attributes=()):
126 """Initialize a figure."""
127 self.fname = fname
128 self.caption = caption
129 self.name = name
130 self.attributes = attributes
132 def _repr_org(self):
133 s = []
134 for backend, attrs in self.attributes:
135 s += [f"#+attr_{backend}: {attrs}"]
137 if self.name:
138 s += [f"#+name: {self.name}"]
140 if self.caption:
141 s += [f"#+caption: {self.caption}"]
143 s += [f"[[{self.fname}]]"]
145 return "\n".join(s) + "\n"
147 def _repr_mimebundle_(self, include, exclude, **kwargs):
148 """Provide a mimebundle representation.
150 repr_mimebundle should accept include, exclude and **kwargs.
151 """
152 data = {"text/org": self._repr_org()}
153 if include:
154 data = {k: v for (k, v) in data.items() if k in include}
155 if exclude:
156 data = {k: v for (k, v) in data.items() if k not in exclude}
157 return data
160class Table:
161 """A Table object for org."""
163 def __init__(self, data, headers=None, caption=None, name=None, attributes=()):
164 """Initialize a table."""
165 self.data = data
166 self.headers = headers
167 self.caption = caption
168 self.name = name
169 self.attributes = attributes
171 def _repr_org(self):
172 """Provide an org representation."""
173 s = []
174 for backend, attributes in self.attributes:
175 s += [f"#+attr_{backend}: {attributes}"]
177 if self.name:
178 s += [f"#+name: {self.name}"]
180 if self.caption:
181 s += [f"#+caption: {self.caption}"]
183 s += [tabulate.tabulate(self.data, self.headers, tablefmt="orgtbl")]
185 return "\n".join(s)
187 def _repr_mimebundle_(self, include, exclude, **kwargs):
188 """Provide a mimebundle representation.
190 repr_mimebundle should accept include, exclude and **kwargs
191 """
192 data = {"text/org": self._repr_org()}
193 if include:
194 data = {k: v for (k, v) in data.items() if k in include}
195 if exclude:
196 data = {k: v for (k, v) in data.items() if k not in exclude}
197 return data
200# * Rich displays for org-mode
203class OrgFormatter(IPython.core.formatters.BaseFormatter):
204 """A special formatter for org objects."""
206 format_type = IPython.core.formatters.Unicode("text/org")
207 print_method = IPython.core.formatters.ObjectName("_repr_org_")
210try:
211 ip = get_ipython()
212 ip.display_formatter.formatters["text/org"] = OrgFormatter()
213 ytv_f = ip.display_formatter.formatters["text/org"]
214 ytv_f.for_type_by_name("IPython.lib.display", "YouTubeVideo", lambda V: f"{V.src}")
215# get_ipython is not defined for tests I think.
216except NameError:
217 pass