Skip to content

Commit 36e4237

Browse files
authored
Main initial commit
Adding the PY and INX file as well as a pretty standard .gitignore. Very first commit.
1 parent ecf2125 commit 36e4237

File tree

3 files changed

+263
-0
lines changed

3 files changed

+263
-0
lines changed

.gitignore

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Python-specific files
2+
__pycache__/
3+
*.py[cod]
4+
5+
# OS-specific files
6+
.DS_Store
7+
Thumbs.db
8+
9+
# IDE/Editor specific files
10+
.vscode/
11+
.idea/
12+
13+
# Build artifacts
14+
/build/
15+
/dist/
16+
17+
# Files with sensitive information
18+
*.env
19+
config/settings.json
20+

ink_sync.inx

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--Copyright (C) [2023] [Simon Heggie], [[email protected]]-->
3+
<!--Copyright (C) [2021] [Matt Cottam (quick_export)], [[email protected]]-->
4+
<!--This program is free software; you can redistribute it and/or modify-->
5+
<!--it under the terms of the GNU General Public License as published by-->
6+
<!--the Free Software Foundation; either version 2 of the License, or-->
7+
<!--(at your option) any later version.-->
8+
<!--This program is distributed in the hope that it will be useful,-->
9+
<!--but WITHOUT ANY WARRANTY; without even the implied warranty of-->
10+
<!--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the-->
11+
<!--GNU General Public License for more details.-->
12+
<!--You should have received a copy of the GNU General Public License-->
13+
<!--along with this program; if not, write to the Free Software-->
14+
<!--Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.-->
15+
16+
<!-- #############################################################################-->
17+
<!-- # Ink Sync - Quickly sync Inkscape svg, plain svg, and png-->
18+
<!-- # After setting the options in the main dialogue-->
19+
<!-- # 'Overwrite Existing Files' activates sync behavior-->
20+
<!-- # Assign a shortcut in Inkscape Edit>Preferences>Interface>Keyboard to org.inkscape.simonh.ink_sync.noprefs-->
21+
<!-- # For shortcut triggered quick export-->
22+
<!-- # Requires Inkscape 1.1+ (1.3 tested) -->
23+
<!-- #############################################################################-->
24+
25+
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
26+
<name>Ink Sync</name>
27+
<id>org.inkscape.simonh.ink_sync</id>
28+
<param name="notebook_main" type="notebook">
29+
<page name="settings_page" gui-text="Settings">
30+
<hbox>
31+
<param name="export_svg_cb" type="boolean" gui-text="Export Inkscape SVG" gui-description="Export Inkscape SVG">true</param>
32+
<param name="export_svg_ttp_cb" type="boolean" gui-text="Export Inkscape SVG (Text to Path)" gui-description="Export Inkscape SVG (Text to path)">true</param>
33+
</hbox>
34+
<hbox>
35+
<param name="export_svg_plain_cb" type="boolean" gui-text="Export Plain SVG" gui-description="Export Plain SVG">true</param>
36+
<param name="export_svg_plain_ttp_cb" type="boolean" gui-text="Export Plain SVG (Text to path)" gui-description="Export Plain SVG (Text to path)">true</param>
37+
</hbox>
38+
<param name="export_png_cb" type="boolean" gui-text="Export PNG" gui-description="Export PNG">true</param>
39+
<param name="png_dpi" type="int" min="10" max="99999999" gui-text="PNG dpi">96</param>
40+
<separator/>
41+
<param name="export_pdf_cb" type="boolean" gui-text="Export PDF" gui-description="Export PDF Document">true</param>
42+
<param name="export_html5_cb" type="boolean" gui-text="Export HTML5" gui-description="Export HTML5 Canvas">true</param>
43+
<separator/>
44+
<param type="path" name="save_path" gui-text="File Save Path" mode="folder">None Selected</param>
45+
<separator/>
46+
<param name="overwrite_existing_file" type="boolean" gui-text="Overwrite Existing File" gui-description="If checked, the file will be overwritten instead of creating a new file with a unique timestamp.">false</param>
47+
</page>
48+
<page name="about_page" gui-text="About">
49+
<label>
50+
Ink Sync - Quickly sync Inkscape svg, plain svg, png, pdf and html5 canvas to other apps.
51+
</label>
52+
<label>
53+
Inkscape 1.1+
54+
</label>
55+
<label appearance="url">
56+
[Your new extension's URL or contact info]
57+
</label>
58+
<label appearance="url">
59+
[Additional URLs or information as needed]
60+
</label>
61+
<label>
62+
* This is not a replacement for saving or Inkscape autosave :) ---
63+
Appears at Extensions>Export ---
64+
'Overwrite Existing Files' activates sync behavior ---
65+
After setting the options in the main dialogue ---
66+
Assign a shortcut in Inkscape Edit>Preferences>Interface>Keyboard to
67+
</label>
68+
<label appearance="header">org.inkscape.simonh.ink_sync.noprefs
69+
</label>
70+
<label>
71+
For shortcut triggered quick export --- Not 100% sure where the PDF and HTML5 settings are pulled from, presume from last used save settings.
72+
</label>
73+
</page>
74+
</param>
75+
<effect needs-live-preview="false">
76+
<object-type>path</object-type>
77+
<effects-menu>
78+
<submenu name="Export"/>
79+
</effects-menu>
80+
</effect>
81+
<script>
82+
<command location="inx" interpreter="python">ink_sync.py</command>
83+
</script>
84+
</inkscape-extension>

ink_sync.py

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
#!/usr/bin/env python
2+
# coding=utf-8
3+
#
4+
# Copyright (C) [2023] [Simon Heggie], [[email protected]]
5+
# Copyright (C) [2021] [Matt Cottam (quick_export)], [[email protected]]
6+
# This program is free software; you can redistribute it and/or modify
7+
# it under the terms of the GNU General Public License as published by
8+
# the Free Software Foundation; either version 2 of the License, or
9+
# (at your option) any later version.
10+
#
11+
# This program is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU General Public License
17+
# along with this program; if not, write to the Free Software
18+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
#
20+
#
21+
# #############################################################################
22+
# Quick Export - Quickly sync Inkscape svg, plain svg, and png
23+
# Overwrite existing file provides the syncing behavior
24+
# After setting the options in the main dialogue
25+
# Assign a shortcut in Inkscape Edit>Preferences>Interface>Keyboard to org.inkscape.simonh.ink_sync.noprefs
26+
# For shortcut triggered quick export
27+
# It does require that you have saved
28+
# Your svg file at least once before using (will not work on an unsaved svg)
29+
# Requires Inkscape 1.1+ (1.3 tested)
30+
# #############################################################################
31+
32+
import inkex
33+
from inkex import command
34+
from pathlib import Path
35+
from datetime import datetime
36+
import sys
37+
import os
38+
39+
def command_line_call(self):
40+
# Current date and time to time stamp
41+
timestamp = datetime.today().replace(microsecond=0)
42+
timestamp_suffix = str(timestamp.strftime('%Y-%m-%d-%H-%M-%S'))
43+
44+
# Get output directory
45+
my_file_path = self.options.input_file
46+
47+
# Collect export format options
48+
my_export_path = self.options.save_path
49+
50+
# Get name of currently open Inkscape file
51+
my_filename = self.svg.name
52+
53+
# Check to see if user has saved file at least once
54+
if len(my_filename) < 2:
55+
inkex.errormsg('Please Save Your File First')
56+
return
57+
58+
# Build a formatted string for command line actions
59+
my_actions = '--actions='
60+
61+
# Use the original filename without timestamp if overwrite is true
62+
if self.options.overwrite_existing_file == 'true':
63+
my_svg_export_filename_path = my_export_path + '/' + my_filename
64+
my_svg_plain_export_filename_path = my_export_path + '/' + my_filename.replace('.svg', '_plain.svg')
65+
my_png_export_filename_path = my_export_path + '/' + my_filename.replace('.svg', '.png')
66+
my_pdf_export_filename_path = my_export_path + '/' + my_filename.replace('.svg', '.pdf')
67+
my_html5_export_filename_path = my_export_path + '/' + my_filename.replace('.svg', '.html')
68+
else:
69+
my_svg_export_filename_path = my_export_path + '/' + my_filename.replace('.svg', '_' + timestamp_suffix + '.svg')
70+
my_svg_plain_export_filename_path = my_export_path + '/' + my_filename.replace('.svg', '_' + timestamp_suffix + '_plain.svg')
71+
my_png_export_filename_path = my_export_path + '/' + my_filename.replace('.svg', '_' + timestamp_suffix + '.png')
72+
my_pdf_export_filename_path = my_export_path + '/' + my_filename.replace('.svg', '_' + timestamp_suffix + '.pdf')
73+
my_html5_export_filename_path = my_export_path + '/' + my_filename.replace('.svg', '_' + timestamp_suffix + '.html')
74+
75+
# Get png dpi setting
76+
png_dpi = self.options.png_dpi
77+
78+
# Check which export file formats have been selected by user
79+
if self.options.export_svg_cb == 'true':
80+
export_svg_actions = f'export-filename:{my_svg_export_filename_path};export-do;'
81+
my_actions = my_actions + export_svg_actions
82+
83+
if self.options.export_svg_plain_cb == 'true':
84+
export_svg_plain_actions = f'export-filename:{my_svg_plain_export_filename_path};export-plain-svg;export-do;'
85+
my_actions = my_actions + export_svg_plain_actions
86+
87+
if self.options.export_png_cb == 'true':
88+
export_png_actions = f'export-filename:{my_png_export_filename_path};export-dpi:{png_dpi};export-do;'
89+
my_actions = my_actions + export_png_actions
90+
91+
if self.options.export_pdf_cb == 'true':
92+
export_pdf_actions = f'export-filename:{my_pdf_export_filename_path};export-do;'
93+
my_actions = my_actions + export_pdf_actions
94+
95+
if self.options.export_html5_cb == 'true':
96+
export_html5_actions = f'export-filename:{my_html5_export_filename_path};export-do;'
97+
my_actions = my_actions + export_html5_actions
98+
99+
# Any text to path export actions need to be at end of action list
100+
if self.options.export_svg_ttp_cb == 'true':
101+
export_svg_actions = f'export-text-to-path;export-filename:{my_svg_export_filename_path};export-do;'
102+
my_actions = my_actions + export_svg_actions
103+
104+
if self.options.export_svg_plain_ttp_cb == 'true':
105+
export_svg_actions = f'export-text-to-path;export-filename:{my_svg_plain_export_filename_path};export-do;'
106+
my_actions = my_actions + export_svg_actions
107+
108+
# Exit if no export file formats have been selected
109+
if my_actions == '--actions=':
110+
inkex.errormsg('Please Select At Least One Export Format')
111+
return
112+
113+
# Redirect standard error to suppress warnings and errors
114+
original_stderr = sys.stderr
115+
sys.stderr = open('/dev/null', 'w')
116+
117+
# Set the path for the log file to the user's home directory to avoid permission issues
118+
log_file_path = os.path.join(os.path.expanduser('~'), 'ink_sync_error.log')
119+
120+
try:
121+
# Check to make sure export directory exists
122+
if Path(my_export_path).is_dir():
123+
inkex.command.inkscape(my_file_path, my_actions)
124+
else:
125+
inkex.errormsg('Please Select An Export Folder')
126+
except Exception as e:
127+
# Log the exception to a file in the user's home directory
128+
with open(log_file_path, "a") as log_file:
129+
log_file.write(f"An error occurred: {e}\n")
130+
finally:
131+
# Restore original stderr
132+
sys.stderr.close()
133+
sys.stderr = original_stderr
134+
135+
class InkSync(inkex.EffectExtension):
136+
def add_arguments(self, pars):
137+
pars.add_argument("--notebook_main", type=str, dest="notebook_main", default=0)
138+
139+
pars.add_argument("--export_svg_cb", type=str, dest="export_svg_cb", default='true')
140+
pars.add_argument("--export_svg_ttp_cb", type=str, dest="export_svg_ttp_cb", default='true')
141+
142+
pars.add_argument("--export_svg_plain_cb", type=str, dest="export_svg_plain_cb", default='true')
143+
pars.add_argument("--export_svg_plain_ttp_cb", type=str, dest="export_svg_plain_ttp_cb", default='true')
144+
145+
pars.add_argument("--export_png_cb", type=str, dest="export_png_cb", default='true')
146+
pars.add_argument("--png_dpi", type=int, dest="png_dpi", default=96)
147+
148+
pars.add_argument("--export_pdf_cb", type=str, dest="export_pdf_cb", default='true')
149+
pars.add_argument("--export_html5_cb", type=str, dest="export_html5_cb", default='true')
150+
151+
pars.add_argument("--save_path", type=str, dest="save_path", default=str(Path.home()))
152+
pars.add_argument("--overwrite_existing_file", type=str, dest="overwrite_existing_file", default='false')
153+
154+
def effect(self):
155+
command_line_call(self)
156+
157+
if __name__ == '__main__':
158+
InkSync().run()
159+

0 commit comments

Comments
 (0)