Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Python script for selecting the visible layers in the diagrams.net (drawio) generated drawings.

27 views
Skip to first unread message

Wojciech Zabołotny

unread,
Oct 6, 2022, 7:57:57 AM10/6/22
to
Drawio (diagrams.net) is a wonderful package enbling creating professional
diagrams.
What was lacking for a long time: https://github.com/jgraph/drawio-desktop/issues/405
, https://github.com/jgraph/drawio-desktop/issues/737 ,
was a possibility to select which layers should be exported to PDF using the
command line tool.
That's essential when one needs to prepare the slides in the beamer, where
in consecutive slides certain objects are appearing or disappering, or
change somehow.
As a workaround, I have prepared a Python script that is able to switch on
and off the layer visibility in a XML file prepared in drawio.

#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.15.2).
# To extract the files from this archive, save it to some FILE, remove
# everything before the '#!/bin/sh' line above, then type 'sh FILE'.
#
lock_dir=_sh16182
# Made on 2022-10-06 13:55 CEST by <wzab@WZabHP>.
# Source directory was '/tmp/y/wzab-code-lib/drawio-support'.
#
# Existing files will *not* be overwritten, unless '-c' is specified.
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 3431 -rwxr-xr-x drawio_select_layers.py
#
MD5SUM=${MD5SUM-md5sum}
f=`${MD5SUM} --version | egrep '^md5sum .*(core|text)utils'`
test -n "${f}" && md5check=true || md5check=false
${md5check} || \
echo 'Note: not verifying md5sums. Consider installing GNU coreutils.'
if test "X$1" = "X-c"
then keep_file=''
else keep_file=true
fi
echo=echo
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=
locale_dir=
set_echo=false

for dir in $PATH
do
if test -f $dir/gettext \
&& ($dir/gettext --version >/dev/null 2>&1)
then
case `$dir/gettext --version 2>&1 | sed 1q` in
*GNU*) gettext_dir=$dir
set_echo=true
break ;;
esac
fi
done

if ${set_echo}
then
set_echo=false
for dir in $PATH
do
if test -f $dir/shar \
&& ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
then
locale_dir=`$dir/shar --print-text-domain-dir`
set_echo=true
break
fi
done

if ${set_echo}
then
TEXTDOMAINDIR=$locale_dir
export TEXTDOMAINDIR
TEXTDOMAIN=sharutils
export TEXTDOMAIN
echo="$gettext_dir/gettext -s"
fi
fi
IFS="$save_IFS"
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null
then if (echo -n test; echo 1,2,3) | grep n >/dev/null
then shar_n= shar_c='
'
else shar_n=-n shar_c= ; fi
else shar_n= shar_c='\c' ; fi
f=shar-touch.$$
st1=200112312359.59
st2=123123592001.59
st2tr=123123592001.5 # old SysV 14-char limit
st3=1231235901

if touch -am -t ${st1} ${f} >/dev/null 2>&1 && \
test ! -f ${st1} && test -f ${f}; then
shar_touch='touch -am -t $1$2$3$4$5$6.$7 "$8"'

elif touch -am ${st2} ${f} >/dev/null 2>&1 && \
test ! -f ${st2} && test ! -f ${st2tr} && test -f ${f}; then
shar_touch='touch -am $3$4$5$6$1$2.$7 "$8"'

elif touch -am ${st3} ${f} >/dev/null 2>&1 && \
test ! -f ${st3} && test -f ${f}; then
shar_touch='touch -am $3$4$5$6$2 "$8"'

else
shar_touch=:
echo
${echo} 'WARNING: not restoring timestamps. Consider getting and
installing GNU '\''touch'\'', distributed in GNU coreutils...'
echo
fi
rm -f ${st1} ${st2} ${st2tr} ${st3} ${f}
#
if test ! -d ${lock_dir} ; then :
else ${echo} "lock directory ${lock_dir} exists"
exit 1
fi
if mkdir ${lock_dir}
then ${echo} "x - created lock directory ${lock_dir}."
else ${echo} "x - failed to create lock directory ${lock_dir}."
exit 1
fi
# ============= drawio_select_layers.py ==============
if test -n "${keep_file}" && test -f 'drawio_select_layers.py'
then
${echo} "x - SKIPPING drawio_select_layers.py (file already exists)"

else
${echo} "x - extracting drawio_select_layers.py (text)"
sed 's/^X//' << 'SHAR_EOF' > 'drawio_select_layers.py' &&
#!/usr/bin/python3
"""
This script modifies the visibility of layers in the XML
file with diagram generated by drawio.
X
It works around the problem of lack of a possibility to export
only the selected layers from the CLI version of drawio.
X
Written by Wojciech M. Zabolotny 6.10.2022
(wzab01<at>gmail.com or wojciech.zabolotny<at>pw.edu.pl)
X
The code is published under LGPL V2 license
"""
from lxml import etree as let
import xml.etree.ElementTree as et
import xml.parsers.expat as pe
from io import StringIO
import os
import sys
import shutil
import zlib
import argparse
X
PARSER = argparse.ArgumentParser()
PARSER.add_argument("--layers", help="Selected layers, \"all\", comma separated list of integers or integer ranges like \"0-3,6,7\"", default="all")
PARSER.add_argument("--layer_prefix", help="Layer name prefix", default="Layer_")
PARSER.add_argument("--outfile", help="Output file", default="output.drawio")
PARSER.add_argument("--infile", help="Input file", default="input.drawio")
ARGS = PARSER.parse_args()
X
INFILENAME = ARGS.infile
OUTFILENAME = ARGS.outfile
X
# Find all elements with 'value' starting with the layer prefix.
# Return tuples with the element and the rest of 'value' after the prefix.
def find_layers(el_start):
X res = []
X for el in el_start:
X val = el.get('value')
X if val is not None:
X if val.find(ARGS.layer_prefix) == 0:
X # This is a layer element. Add it, and its name
X # after the prefix to the list.
X res.append((el,val[len(ARGS.layer_prefix):]))
X continue
X # If it is not a layer element, scan its children
X res.extend(find_layers(el))
X return res
X
# Analyse the list of visible layers, and create the list
# of layers that should be visible. Customize this part
# if you want a more sophisticate method for selection
# of layers.
# Now only "all", comma separated list of integers
# or ranges of integers are supported.
X
def build_visible_list(layers):
X if layers == "all":
X return layers
X res = []
X for lay in layers.split(','):
X # Is it a range?
X s = lay.find("-")
X if s > 0:
X # This is a range
X first = int(lay[:s])
X last = int(lay[(s+1):])
X res.extend(range(first,last+1))
X else:
X res.append(int(lay))
X return res
X
def is_visible(layer_tuple,visible_list):
X if visible_list == "all":
X return True
X if int(layer_tuple[1]) in visible_list:
X return True
X
try:
X EL_ROOT = et.fromstring(open(INFILENAME,"r").read())
except et.ParseError as perr:
X # Handle the parsing error
X ROW, COL = perr.position
X print(
X "Parsing error "
X + str(perr.code)
X + "("
X + pe.ErrorString(perr.code)
X + ") in column "
X + str(COL)
X + " of the line "
X + str(ROW)
X + " of the file "
X + INFILENAME
X )
X sys.exit(1)
X
visible_list = build_visible_list(ARGS.layers)
X
layers = find_layers(EL_ROOT)
for layer_tuple in layers:
X if is_visible(layer_tuple,visible_list):
X print("set "+layer_tuple[1]+" to visible")
X layer_tuple[0].attrib['visible']="1"
X else:
X print("set "+layer_tuple[1]+" to invisible")
X layer_tuple[0].attrib['visible']="0"
X
# Now write the modified file
t=et.ElementTree(EL_ROOT)
with open(OUTFILENAME, 'w') as f:
X t.write(f, encoding='unicode')
X
SHAR_EOF
(set 20 22 10 06 12 57 18 'drawio_select_layers.py'
eval "${shar_touch}") && \
chmod 0755 'drawio_select_layers.py'
if test $? -ne 0
then ${echo} "restore of drawio_select_layers.py failed"
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'drawio_select_layers.py': 'MD5 check failed'
) << \SHAR_EOF
2f48cb5d33e1f46dc4b624f12796e916 drawio_select_layers.py
SHAR_EOF

else
test `LC_ALL=C wc -c < 'drawio_select_layers.py'` -ne 3431 && \
${echo} "restoration warning: size of 'drawio_select_layers.py' is not 3431"
fi
fi
if rm -fr ${lock_dir}
then ${echo} "x - removed lock directory ${lock_dir}."
else ${echo} "x - failed to remove lock directory ${lock_dir}."
exit 1
fi
exit 0

Wojciech Zabołotny

unread,
Oct 6, 2022, 8:00:47 AM10/6/22
to
Drawio (diagrams.net) is a wonderful package enbling creating professional
diagrams.
What was lacking for a long time: https://github.com/jgraph/drawio-desktop/issues/405
, https://github.com/jgraph/drawio-desktop/issues/737 ,
was a possibility to select which layers should be exported to PDF using the
command line tool.
That's essential when one needs to prepare the slides in the beamer, where
in consecutive slides certain objects are appearing or disappering, or
change somehow.
As a workaround, I have prepared a Python script that is able to switch on
and off the layer visibility in a XML file prepared in drawio.

Because now google.groups is the main way to access alt.sources, and it
is known to corrupt shar archives, this version of post containd the
base64-encoded archive with my script.

H4sICI60PmMAA2RyYXdpb19zZWxlY3RfbGF5ZXJzLnB5AJ1XbW8bNwz+fr9Cu3zwHeJcnRTogGDu
EBRpZ8B5QZKtw9LAkH20rVWWDpKujvPrR0q6812SrsOMAHFE8iFFPiSVg5/e1Na8mQv1ptq5tVZv
kzRNk7u1sMwujKgc2+hSLAVY5tbAvgkr5kIKt2N6ySTfgbFMKC/782KaLIUEthVuzUrBV4Zv2AoU
GO6gZPMdKw3fCl0kycSxrTZfLeNG16r09pXRcwmbALz4Sr85q7RtPTrN4LHSxiVayZ23sSBhQeAx
lKXRGy/4MJ2wb3gitCKg1vFnI5wDRcF81n8vBCzW7KJgf/G5ltqpHXtXHI+Kk9HJSZJtn/h8dPwL
d+9XGy5ksUBsbTDwYFc8NUakUm0LKOuiknmC6QO20CUwzGJVz6WwawwR7wmGTT9dT9kfJ0yKBSgL
Pt0+avm4kUxs6H4MnAFg3DIJLolnKC78eXGOWQLl7qJOX6XixuK9C8wUdySuIOAL3aDfOiPUanLV
mGnbfLO7/dd17YRs/nqSYt5852blnSTJ9dnN7fkNG7dHxZlZ1RTbtY8iy6NKwctyxqMsS4+OQrnS
IVuDrMbpbb+MQ/Yl5VJ+QTnmfMOxzAjvSYS5dFRQoRysqOJYkPidGa5WyFMpvgICjI7eDt8Nf/6S
IkoJS15LNybU9N+DmlUGluKxDW1Kh0zxDRE0Slo4L5x9H1HXjjqiBbuqXVU7Fs9aGO2Pi0DS76MJ
1QObqNewhOpBnd18usUCRURfJMK0WJpkcvlxMj2/PLs4Rw1SLIKH5Or3u+eSeJMkOWAfBTYsJpJB
4KENDT/4xmUNA2YdNw75FU6pF31eY/YKBLgBVxucGXUlwe7VIhzjcR4YCKVugPnSIUyYFAEKL433
V+Us0CYDOfPe89OE4QcBMPz7B//HEokCkmZVoxWU6IMOUBFksQKXRXd5KxVLr4C9rLRjl1rB3nIv
LyiQzOeqy6Ocjcds1DegzwHzMxZ/eMxPvH7BzsqSCTf0eRCYXc+9VwCe54Pmo083tkjxQh+TUfCq
AgwS8zTEiO8lqFcCPn3I8xfWC62wpjW0ggM2wSZ0TVaeXWKIy4MrH/1iLWRpQCXdQODRUSD92kW3
JrAD1YhsZ4rLnYX2YkQIv4QktMOCErUwgPOhVUPL/X5ya07zTNcSlxA05gX7UFunN+KJzGhSIyfQ
Dsu50zXbcqIibj+DW0ZXqODEglxsAPdk6fkUtg+umK47Yvil3jK/o/zA+fEUI/t2fnWnGyfvdUVz
F0pcX8T4eY0ZncVbzAgqC54j7UV7caSeD6ClX8xtEL/eIyijJol3sRVu3mwwHOSn3dJbKj0PAf/a
CggJ7UInpEdpr4Use/+8D7o94KF60qUwmKQx5YLud39qH/q8lLwnz+zhMZG3p9Mhm/eQedQhmaL2
XhekfdbVnX6JHvKczl9wlEoibFOPUIqZn23Dbo32xemevixRg31nYreJZXPFBvf++CGnGnWBXrdP
nNkFyfl0dnN1dUdjzhX0HrD+EZBpvGG2XwTD1KR5gb1UZpgdeFxARa+Rwu/zc2OQIP5JYUyAPWC/
YffJ0Hi0XWjwA+l58c3V5yH7cDVFt2RT4GtO+H4hYWXoXm3c6XXXnKWt4BBXism8PT2q8o4gzbpq
FT6NyDa8b75j4TO30LLeqBc+MNKeLrVimCgKXijj3V5V9k/grvI+u/4wGOFLC4mJvXWMi7jPiNca
fD+mLeo37d1bfrHCeRK7uGHLvptbBv53uu7rlFpwLD3s0/AwpaUT7Tr93tUaPRTcYUXm94OoOHgY
p8chQ/2++6Enof6Pr1GaxJm8xdd/4Gr8r6b05UrcGDneeVbvk+lfJ75JOo+iIRtsBzl1wjIE7wqP
nC2HDBRSDuk3HtRKEPvwJZH8AyBoPD5nDQAA

Wojciech Zabolotny

unread,
Oct 8, 2022, 5:16:36 PM10/8/22
to
The maintained version of that script together with a demonstration of its use is available in a github repository: https://github.com/wzab/wzab-code-lib/tree/main/drawio-support
0 new messages