Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Control texmode via SVG attribute #194

Merged
merged 9 commits into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/pylint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,17 @@ jobs:
files: "**/*.py"

- name: Install python
if: steps.chaged-files.output.any_changed == 'true'
if: steps.changed-files.output.any_changed == 'true'
uses: actions/setup-python@v3
with:
python-version: 3.x


- run: pip install --upgrade pip
if: steps.chaged-files.output.any_changed == 'true'
if: steps.changed-files.output.any_changed == 'true'
- run: pip install .
if: steps.chaged-files.output.any_changed == 'true'
if: steps.changed-files.output.any_changed == 'true'
- run: pip install pylint==2.16.*
if: steps.chaged-files.output.any_changed == 'true'
if: steps.changed-files.output.any_changed == 'true'
- run: pylint --rcfile=pylintrc ${{ steps.changed-files.outputs.all_changed_files }}
if: steps.chaged-files.output.any_changed == 'true'
if: steps.changed-files.output.any_changed == 'true'
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
## [Unreleased]

### Added
- Adding option to specify texmode via a SVG attribute (see --texmode)
### Changed
### Deprecated
### Removed
### Fixed
- Fixed string encoding exception when using stdout as output
### Security

## v3.0.1 - 14/01/2023
Expand Down
2 changes: 1 addition & 1 deletion docs/inkscapeguide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Inkscape guide
Svg2TikZ originally started out as an Inkscape extension and most users will
probably use it this way.

If installed properly, the extension should appear in the extensions menu. If you
If installed properly, the extension should appear in the extensions menu under `Export`. If you
can't find it see the :ref:`inkscape-install` for installation details.


Expand Down
49 changes: 41 additions & 8 deletions svg2tikz/tikz_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
__maintainer__ = "Deville Louis"
__email__ = "[email protected]"


import sys

from textwrap import wrap
Expand Down Expand Up @@ -70,7 +69,6 @@
"polygon",
]


SPECIAL_TEX_CHARS = ["$", "\\", "%", "_", "#", "{", r"}", "^", "&"]
SPECIAL_TEX_CHARS_REPLACE = [
r"\$",
Expand Down Expand Up @@ -452,9 +450,17 @@ def _set_up_options(self):
"--texmode",
dest="texmode",
default="escape",
choices=("math", "escape", "raw"),
help="Set text mode (escape, math, raw). Defaults to 'escape'",
choices=("math", "escape", "raw", "attribute"),
help="Set text mode (escape, math, raw, attribute). Defaults to 'escape'",
)
parser.add_argument(
"--texmode-attribute",
default=None,
action="store",
dest="texmode_attribute",
help="The SVG attribute that specifies how to handle text",
)

parser.add_argument(
"--markings",
dest="markings",
Expand Down Expand Up @@ -847,7 +853,7 @@ def style_to_tz(self, node=None):
options.append(f"{tikzname}={self.round_value(float(value))}")
elif valuetype == DICT:
if tikzname:
options.append(f"{tikzname}={data.get(value,'')}")
options.append(f"{tikzname}={data.get(value, '')}")
else:
options.append(data.get(value, ""))
elif valuetype == DIMENSION:
Expand Down Expand Up @@ -1226,14 +1232,34 @@ def _handle_shape(self, node):

return "", []

def _find_attribute_in_hierarchy(self, current, attr):
"""Try to find the attribute with the given name in the current node or any of its parents.
If the attribute is found, return its value, otherwise None."""
while current is not None:
value = current.get(attr)
if value:
return value
return self._find_attribute_in_hierarchy(current.getparent(), attr)

return None

def _handle_text(self, node):
if self.options.ignore_text:
return "", []

raw_textstr = node.get_text(" ").strip()
if self.options.texmode == "raw":
mode = self.options.texmode

if mode == "attribute":
attribute = self._find_attribute_in_hierarchy(
node, self.options.texmode_attribute
)
if attribute:
mode = attribute

if mode == "raw":
textstr = raw_textstr
elif self.options.texmode == "math":
elif mode == "math":
textstr = f"${raw_textstr}$"
else:
textstr = escape_texchars(raw_textstr)
Expand Down Expand Up @@ -1437,7 +1463,7 @@ def save_raw(self, _):
else:
out = self.output_code

if isinstance(self.options.output, io.BufferedWriter):
if isinstance(self.options.output, (io.BufferedWriter, io.FileIO)):
out = out.encode("utf8")

self.options.output.write(out)
Expand Down Expand Up @@ -1479,6 +1505,13 @@ def convert(self, svg_file=None, no_output=False, **kwargs):
print_version_info()
return ""

if (
self.options.texmode == "attribute"
and self.options.texmode_attribute is None
):
print("Need to specify a texmode attribute with --texmode-attribute")
return ""

if svg_file is not None:
self.options.input_file = svg_file

Expand Down
2 changes: 2 additions & 0 deletions svg2tikz/tikz_export_effect.inx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@
<option value="escape">Escape special TeX chars</option>
<option value="raw">Raw TeX</option>
<option value="math">Math</option>
<option value="attribute">Defined by attribute</option>
</param>
<param name="texmode-attribute" type="string" gui-text="Texmode SVG attribute" gui-description="The text interpretation mode will be defined per SVG object by an attribute with this name."></param>
<param name="notext" type="boolean" gui-text="Ignore the text" gui-description="The text will not be included in the figure">false</param>
<separator />
<label appearance="header" gui-description="How should the markers be interpreted">Markings</label>
Expand Down
2 changes: 2 additions & 0 deletions svg2tikz/tikz_export_output.inx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@
<option value="escape">Escape special TeX chars</option>
<option value="raw">Raw TeX</option>
<option value="math">Math</option>
<option value="attribute">Defined by attribute</option>
</param>
<param name="texmode-attribute" type="string" gui-text="Texmode SVG attribute" gui-description="The text interpretation mode will be defined per SVG object by an attribute with this name."></param>
<param name="notext" type="boolean" gui-text="Ignore the text" gui-description="The text will not be included in the figure">false</param>
<separator />
<label appearance="header" gui-description="How should the markers be interpreted">Markings</label>
Expand Down
7 changes: 7 additions & 0 deletions tests/test_complete_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,13 @@ def test_nodes_and_transform(self):
filename = "nodes_and_transform"
create_test_from_filename(filename, self)

def test_attribute_texmode(self):
"""Test per SVG object texmode with attribute"""
filename = "attribute_texmode"
create_test_from_filename(
filename, self, texmode="attribute", texmode_attribute="data-texmode"
)


if __name__ == "__main__":
unittest.main()
71 changes: 71 additions & 0 deletions tests/testfiles/attribute_texmode.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
73 changes: 73 additions & 0 deletions tests/testfiles/attribute_texmode.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}

\begin{document}
\definecolor{ceecbff}{RGB}{238,203,255}
\definecolor{cbae1ff}{RGB}{186,225,255}


\def \globalscale {1.000000}
\begin{tikzpicture}[y=1cm, x=1cm, yscale=\globalscale,xscale=\globalscale, every node/.append style={scale=\globalscale}, inner sep=0pt, outer sep=0pt]
\path[fill=white] ;



\path[draw=black,miter limit=10.0] (0.9033, 0.9033) -- (6.7141, 5.4208);



\path[draw=black,fill=black,miter limit=10.0] (6.8236, 5.506) -- (6.7344, 5.3192) -- (6.7141, 5.4208) -- (6.6207, 5.4655) -- cycle;



\path[fill=ceecbff] (0.5292, 0.5292) ellipse (0.5292cm and 0.5292cm);



\begin{scope}[fill=black,anchor=south]
\node[text=black,anchor=south] (emphtext) at (0.5159, 0.5159){\emph{emphasized}};



\end{scope}
\path[fill=cbae1ff] (7.4083, 6.0854) ellipse (0.7938cm and 0.7938cm);



\begin{scope}[shift={(-0.0132, 0.0132)}]
\node[text=black,anchor=south] (regulartext) at (7.4083, 5.9796){Text with $\backslash$ and \_};



\end{scope}
\path[draw=black,miter limit=10.0] (2.1167, 5.2917) -- (4.3656, 5.2917) -- (4.3656, 6.0854) -- (6.446, 6.0854);



\path[draw=black,fill=black,miter limit=10.0] (6.585, 6.0854) -- (6.3997, 5.9928) -- (6.446, 6.0854) -- (6.3997, 6.178) -- cycle;



\path[draw=black,miter limit=10.0] (1.2134, 4.9175) -- (1.2144, 2.9104) -- (0.5292, 2.9104) -- (0.5292, 1.2269);



\path[draw=black,fill=black,miter limit=10.0] (0.5292, 1.088) -- (0.4366, 1.2732) -- (0.5292, 1.2269) -- (0.6218, 1.2732) -- cycle;



\path[fill=ceecbff] (1.5875, 5.2917) ellipse (0.5292cm and 0.5292cm);



\begin{scope}[fill=black,anchor=south]
\node[text=black,anchor=south] (mathtext) at (1.5743, 5.2784){$\frac{a}{b}$};



\end{scope}

\end{tikzpicture}
\end{document}
Loading