%% %% This is file `ecgdraw.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% ecgdraw.dtx (with options: `package') %% ________________________________________ %% A package to draw ECG. %% Copyright (C) 2016 Marco Scavino and Ezio Aimé %% All rights reserved %% License information appended \NeedsTeXFormat{LaTeX2e}[2009/01/01] \ProvidesPackage{ecgdraw}[2016/06/29 v.1.0 Draw ECG] \RequirePackage{tikz} \RequirePackage{xparse} \usetikzlibrary{calc} \pgfdeclarelayer{sk@back} \pgfsetlayers{sk@back,main} \ExplSyntaxOn \bool_new:N \sk_ECG_breaklines_bool \bool_new:N \sk_ECG_breaklines_arrow_bool \tikzset { breakindent / .store ~ in = \sk_ECG_breakindent_tl , breakindent = 1cm, breaklines / .is ~ choice, breaklines / true / .code = \bool_set_true:N \sk_ECG_breaklines_bool , breaklines / false / .code = \bool_set_false:N \sk_ECG_breaklines_bool , breaklines / arrow / .code = \bool_set_true:N \sk_ECG_breaklines_bool \bool_set_true:N \sk_ECG_breaklines_arrow_bool , breaklines / no ~ indent /.code = \bool_set_true:N \sk_ECG_breaklines_bool \tl_set:Nn \sk_ECG_breakindent_tl { 0 } , breaklines / .default = true, breaklines = false, ECG ~ title / .store ~ in = \sk_ECG_title_tl, ECG ~ title = {}, ECG ~ title ~ align / .is~choice , ECG ~ title ~ align / center / .code = \tl_set:Nn \sk_ECG_title_align_tl { north } \tl_set:Nn \sk_ECG_title_anchor_tl { south } , ECG ~ title ~ align / right / .code = \tl_set:Nn \sk_ECG_title_align_tl { north ~ east } \tl_set:Nn \sk_ECG_title_anchor_tl { south ~ east } , ECG ~ title ~ align / left / .code = \tl_set:Nn \sk_ECG_title_align_tl { north ~ west } \tl_set:Nn \sk_ECG_title_anchor_tl { south ~ west } , ECG ~ title ~ align = left , grid ~ border / .code = \tl_set:Nn \sk_ECG_gridtp_tl { #1 } \tl_set:Nn \sk_ECG_gridlf_tl { #1 } \tl_set:Nn \sk_ECG_gridrg_tl { #1 } \tl_set:Nn \sk_ECG_gridbt_tl { #1 }, grid ~ top / .store ~ in = \sk_ECG_gridtp_tl, grid ~ bottom / .store ~ in = \sk_ECG_gridbt_tl, grid ~ left / .store ~ in = \sk_ECG_gridlf_tl, grid ~ right / .store ~ in = \sk_ECG_gridrg_tl, grid ~ border = .2cm, } \bool_new:N \sk_ECG_start_bool \DeclareDocumentCommand \ECG { O{} m } { \begin{tikzpicture} \coordinate(sk_end) at (0,0); \sk_ECG:nn { #1 } { #2 } \end{tikzpicture} } \cs_set_nopar:Npn \sk_ECG_env:nnn #1 #2 #3 { \tl_if_empty:nTF { #2 } { \coordinate(sk_end) at (0,\sk_ECG_yshift_dim); } { \coordinate(sk_end) at (#2); } \sk_ECG:nn { #1 } { #3 } \dim_set:Nn \sk_ECG_yshift_dim { \sk_ECG_yshift_dim - 2.5cm } } \dim_new:N \sk_ECG_yshift_dim \dim_new:N \sk_ECG_x_dim \int_new:N \sk_ECG_row_int \int_new:N \sk_ECG_wave_int \DeclareDocumentEnvironment { ecg } { O{} } { \int_zero:N \sk_ECG_row_int \int_zero:N \sk_ECG_wave_int \dim_zero:N \sk_ECG_yshift_dim \DeclareDocumentCommand \ECG { O{} D(){} m } { \dim_zero:N \sk_ECG_x_dim \int_incr:N \sk_ECG_row_int \sk_ECG_env:nnn { ##1 } { ##2 } { ##3 } } \begin{center} \begin{tikzpicture}[#1] } { \tl_if_empty:NF \sk_ECG_title_tl { \node at (current ~ bounding ~ box.\sk_ECG_title_align_tl) [inner ~ sep=\c_zero_dim,anchor=\sk_ECG_title_anchor_tl] {\sk_ECG_title_tl}; } \begin{pgfonlayer}{sk@back} \coordinate(grid_start) at ([xshift=-\sk_ECG_gridlf_tl, yshift=-\sk_ECG_gridbt_tl] current ~ bounding ~ box. south ~ west); \coordinate(grid_stop) at ([xshift=\sk_ECG_gridrg_tl, yshift=\sk_ECG_gridtp_tl] current ~ bounding ~ box.north ~ east); \draw[color=red!20,step=0.1cm,very ~ thin] (grid_start) grid (grid_stop); \draw [color=red!50,step=.5cm](grid_start)grid(grid_stop); \end{pgfonlayer} \end{tikzpicture} \end{center} } \DeclareDocumentEnvironment { ecg* } { O{} } { \int_zero:N \sk:ECG_row_int \int_zero:N \sk:ECG_wave_int \dim_zero:N \sk_ECG_yshift_dim \DeclareDocumentCommand \ECG { O{} D(){} m } { \dim_zero:N \sk_ECG_x_dim \int_incr:N \sk_ECG_row_int \sk_ECG_env:nnn { ##1 } { ##2 } { ##3 } } \begin{tikzpicture}[#1] } { \tl_if_empty:NF \sk_ECG_title_tl { \node at (current ~ bounding ~ box.\sk_ECG_title_align_tl) {\sk_ECG_title_tl}; } \begin{pgfonlayer}{sk@back} \coordinate(grid_start) at ([xshift=-\sk_ECG_gridlf_tl, yshift=-\sk_ECG_gridbt_tl] current ~ bounding ~ box. south ~ west); \coordinate(grid_stop) at ([xshift=\sk_ECG_gridrg_tl, yshift=\sk_ECG_gridtp_tl] current ~ bounding ~ box.north ~ east); \draw[color=red!20,step=0.1cm,very ~ thin] (grid_start) grid (grid_stop); \draw [color=red!50,step=.5cm](grid_start)grid(grid_stop); \end{pgfonlayer} \end{tikzpicture} } \seq_new:N \sk_ECG_seq \cs_set_nopar:Npn \sk_ECG:nn #1 #2 { \tl_clear:N \sk_ECG_onda_tl \seq_clear:N \sk_ECG_seq \bool_set_true:N \sk_ECG_start_bool \seq_set_split:Nnn \sk_ECG_seq { , } { #2 } \seq_map_inline:Nn \sk_ECG_seq { \sk_ECG_use:w ##1 \q_nil { #1 } } } \DeclareDocumentCommand \sk_ECG_use:w { O{} m u\q_nil m } { \int_incr:N \sk_ECG_wave_int \tl_set:Nn \sk_ECG_onda_tl { \draw[thick,rounded ~ corners=0.25mm,line ~ cap=round, shift=(sk_end), #4,#1] } \str_case:nn { #2 } { { ! } { \tl_put_right:Nx \sk_ECG_onda_tl { \cs_if_exist_use:cF { sk_ECG_ #3 } { (0,0) } } } { ? } { \sk_ECG_onda_label:w #3 \q_nil } { i } { \sk_ECG_onda_iso:w #3 \q_nil } { p } { \sk_ECG_onda_p:nnnw #3 \q_nil } { q } { \sk_ECG_onda_q:nw #3 \q_nil } { r } { \sk_ECG_onda_r:nw #3 \q_nil } { s } { \sk_ECG_onda_s:nw #3 \q_nil } { t } { \sk_ECG_onda_t:nw #3 \q_nil } { T } { \tl_put_right:Nx \sk_ECG_onda_tl { (0,0) -- (.1cm,0) -- (.1cm,#3*1cm) -- (.5cm,#3*1cm) -- (.5,0) -- (1,0) } } { * } { \int_decr:N \sk_ECG_wave_int \sk_ECG_onda_ripeti:nw #3 \q_nil { #4 } \tracingmacros=0} } \tl_put_right:Nn \sk_ECG_onda_tl { coordinate (sk_end) let \p1=(current ~ path ~ bounding ~ box.south ~ west), \p2=(current ~ path ~ bounding ~ box.north ~ east) in ~ node (ecg-\int_use:N \sk_ECG_row_int-\int_use:N \sk_ECG_wave_int) [at=(current ~ path ~ bounding ~ box),text ~ width=\x2-\x1,text ~ height=\y2-\y1]{} ; } \str_if_eq:nnF { #2 } { * } { \sk_ECG_onda_tl } \bool_if:NT \sk_ECG_breaklines_bool { \pgfgetlastxy{\sk_ECG_lastx_tl}{\sk_ECG_lasty_tl} \dim_set:Nn \l_tmpa_dim { \textwidth - \sk_ECG_gridlf_tl - \sk_ECG_gridrg_tl - \sk_ECG_lastx_tl } \dim_compare:nT { \l_tmpa_dim < 1.5cm } { \dim_zero:N \sk_ECG_x_dim \dim_set:Nn \sk_ECG_yshift_dim { \sk_ECG_yshift_dim - 2.5cm } \coordinate(sk_end) at (\sk_ECG_breakindent_tl,\sk_ECG_yshift_dim); \bool_if:NT \sk_ECG_breaklines_arrow_bool { \draw[thick,<-,rounded ~ corners]([xshift=-.25cm]sk_end) -| ++ (-.5cm,1.5cm); } } } \bool_if:NT \sk_ECG_start_bool { \bool_set_false:N \sk_ECG_start_bool } } \cs_set_nopar:Npn \sk_ECG_onda_ripeti:nw #1 #2 \q_nil #3 { \group_begin: \prg_replicate:nn { #1 } { \sk_ECG:nn { #3 } { #2 } } \group_end: } \DeclareDocumentCommand \sk_ECG_onda_label:w { O{.5cm} u\q_nil } { \tl_put_right:Nx \sk_ECG_onda_tl { (#1,0) node [ \bool_if:NTF \sk_ECG_start_bool { left } { right } ,name=sk_deriv] { \str_case:nnF { #2 } { { d1 } { I } { d2 } { II } { d3 } { III } { vr } { aVR } { vl } { aVL } { vf } { aVF } { v1 } { V1 } { v2 } { V2 } { v3 } { V3 } { v4 } { V4 } { v5 } { V5 } { v6 } { V6 } } { #2 } } ; \exp_not:N \path(sk_deriv.east) } } \cs_set_nopar:Npn \sk_ECG_onda_iso:w #1 \q_nil { \tl_put_right:Nx \sk_ECG_onda_tl { (0,0) -- ( 0.025 mm * \str_if_eq:nnTF { k } { #1 } { 1000 } { #1 } ,0) } } \cs_set_nopar:Npn \sk_ECG_onda_q:nw #1 #2 \q_nil { \tl_put_right:Nn \sk_ECG_onda_tl { (0,0)--(#1*.0125cm,-#2*.1cm)--(#1*.025cm,0) } } \cs_set_nopar:Npn \sk_ECG_onda_r:nw #1 #2 \q_nil { \tl_put_right:Nn \sk_ECG_onda_tl { (0,0) -- (#1*.0125cm,#2*.1) -- (#1*.025cm,0) } } \cs_set_nopar:Npn \sk_ECG_onda_s:nw #1 #2 \q_nil { \tl_put_right:Nn \sk_ECG_onda_tl { (0,0)--(#1*0.0125cm-0.005cm,-#2*.1cm)--(#1*0.025cm,0) } } \cs_set_nopar:Npn \sk_ECG_onda_t:nw #1 #2 #3\q_nil { \str_case:nn { #1 } { { p } { \tl_put_right:Nn \sk_ECG_onda_tl { (0,0) .. controls (#2*.0625cm,.05cm) and (#2*.075cm,#3*.065cm) .. (#2*.112cm,#3*.1cm) -- (#2*.138cm,#3*.09cm) .. controls (#2*.175cm,#3*.065cm) and (#2*.188cm,.05) .. (#2*.25cm,0) } } { n } { \tl_put_right:Nn \sk_ECG_onda_tl { (0,0) .. controls (#2*.0625cm,-.05cm) and (#2*.075cm,-#3*.065cm) .. (#2*.112cm,-#3*.1cm) -- (#2*.138cm,-#3*.09cm) .. controls (#2*.175cm,-#3*.065cm) and (#2*.188cm,-.05) .. (#2*.25cm,0) } } } } \cs_set_nopar:Npn \sk_ECG_onda_p:nnnw #1 #2 #3 #4 \q_nil { \tl_put_right:Nx \sk_ECG_onda_tl { \str_case:nn { #1 } { { p } { (0,0) -- (.0005*#4,#2#3*.06) -- (.0011*#4,#2#3*.1) -- (.002*#4,#2#3*.06) -- (.0025*#4,.0) } { n } { (0,0) -- (.0005*#4,-#2#3*.06) -- (.0011*#4,-#2#3*.1) -- (.002*#4,-#2#3*.06) -- (.0025*#4,.0) } { d } { (0,0) -- (.01cm,.005cm) -- (#4*0.3333-.01cm,#2*.1cm-.008cm) -- (#4*0.3333+.01cm,#2*.1cm-.008cm) -- (#4*0.6667-.01cm,-#3*.1cm+.008cm) -- (#4*0.6667+.01cm,-#3*.1cm+.008cm) -- (#4-.01cm,.005cm) -- (#4,0) } { b } { (0,0) -- (.01cm,.005cm) -- (#4*1/3-.01cm,#2*0.045cm+.105cm) -- (#4*1/3+.01cm,#2*0.045cm+.105cm) -- (#4*1/2-.01cm,.1cm) -- (#4*1/2+.01cm,.1cm) -- (#4*2/3-.01cm,#3*0.045cm+.105cm) -- (#4*2/3+.01cm,#3*0.045cm+.105cm) -- (#4-.01cm,.005cm) -- (#4,0) } } } } \msg_new:nnn { ECG } { wave ~ defined } { wave ~ "#1" ~ already ~ defined. ~ Change ~ name. } \cs_set_nopar:Npn \sk_ECG_new:nn #1 #2 #3 { \cs_if_exist:cTF { sk_ECG_ #1 } { \msg_warning:nnn { ECG } { wave ~ defined } { #1 } } { \cs_set_nopar:cpn { sk_ECG_ #1 } { #3 } } } \DeclareDocumentCommand \nuovoECG { m O{} m } { \sk_ECG_new:nn { #1 } { #2 } { #3 } } \msg_new:nnn { ECG } { fnotf } { File ~ “#1” ~ not ~ found. ~ Please ~ check ~ your ~ installation.} \file_if_exist:nTF { archivio } { \file_input:n { archivio } } { \msg_warning:nnn { ECG } { fnotf } { archivio } } \ExplSyntaxOff %% \Finale %% Copyright 2016 %% %% Distributable under the LaTeX Project Public License, %% version 1.3c or higher (your choice). The latest version of %% this license is at: http://www.latex-project.org/lppl.txt %% This work is "author-maintained" %% This work consists of this file ECG.dtx, %% and the derived files ECG.sty, archivio.tex and ECG.pdf. %% %% End of file `ecgdraw.sty'.