Ridefinire \@makecaption e \caption

  • Creatore
    Topic
  • #58995
    Up
    0
    Down
    ::


    Ciao,

    vorrei definire una caption tutta mia. Per fare questo sto ridefinendo alcuni comandi della classe report. Nel case specifico il comando \@makecaption.

    A sua volta dove viene usato questo comando? Per intenderci dove trovo il file dove è definito \caption?

    Quello che vorrei fare è disegnare una cornice non banale intorno a ciò che immetto nell’ambiente figure con tikz che contenga anche la caption.

    Michele

Visualizzazione 8 filoni di risposte
  • Autore
    Risposte
    • #58996
      Up
      0
      Down
      ::

      Ciao,

      vorrei definire una caption tutta mia. Per fare questo sto ridefinendo alcuni comandi della classe report. Nel case specifico il comando \@makecaption.

      A sua volta dove viene usato questo comando? Per intenderci dove trovo il file dove è definito \caption?

      Quello che vorrei fare è disegnare una cornice non banale intorno a ciò che immetto nell’ambiente figure con tikz che contenga anche la caption.

      Michele

      Io ridefinirei l’ambiente figure.

      Ciao
      Enrico

    • #58997
      Up
      0
      Down
      ::


      Si è stato il mio primo tentativo, ecco il codice:

      `
      \newlength\figureWidth
      \newenvironment*{tikzgraphic}[4]{%
      % #1 = total picture width(cm)
      % #2 = picture name
      \@float{figure}
      \centering
      \edef\CAP{#3}
      \edef\LAB{#4}
      \begin{tikzpicture}[remember picture]
      \def\Ydist{1ex}
      \def\Xdist{.5ex}
      \def\YH{5ex}
      \def\XH{\YH}
      \def\TH{2ex}
      \pgfmathsetmacro{\PictureWidth}{(#1-(2*(\Xdist+\YH)))*2.54/72}
      \node[inner sep=-\pgflinewidth/2] (figure) at (0,0){\includegraphics[width=\PictureWidth cm]{#2}};
      \edef\ddt{width=\PictureWidth cm}
      %\show\ddt
      \foreach \sign/\loc in {+/north,-/south}{
      \coordinate (A\loc) at ($(figure.\loc)+(\PictureWidth/2,\sign\Ydist)$);
      \coordinate (B\loc) at ($(A\loc)+(0,\sign\YH)$);
      \coordinate (C\loc) at ($(B\loc)-(\PictureWidth,0)$);
      \coordinate (D\loc) at ($(C\loc)+(0,-\sign\YH)$);
      \fill[HEAD](A\loc)–(B\loc)–(C\loc)–(D\loc)–cycle;
      }

      \foreach \sign/\loc in {+/east,-/west}{
      \coordinate (E\loc) at ($(figure.south \loc)+(\sign\Xdist,-\Ydist)$);
      \coordinate (F\loc) at ($(E\loc)+(0,-\YH)$);
      \coordinate (G\loc) at ($(figure.north \loc)+(\sign\Xdist,\Ydist)$);
      \coordinate (H\loc) at ($(G\loc)+(0,+\YH)$);
      \fill[HEAD] (F\loc)arc[radius=\YH,start angle=-90,delta angle=\sign90]–
      ($(current bounding box.north \loc)-(0,\YH)$)
      arc[radius=\YH,start angle={90-\sign 90},delta angle=\sign90]–
      (G\loc)arc[radius={\YH-\TH},start angle=90,delta angle=-\sign90]–
      ($(current bounding box.south \loc)+(-\sign\TH,{2*\YH-\TH})$)
      arc[radius={\YH-\TH},start angle={90-\sign 90},delta angle=-\sign90]–
      cycle;
      }}{\end{tikzpicture}\caption{\CAP}\label{\LAB}\end@float}
      `

      il risultato è questo

      L’intento è di inserire la caption all’interno del rettangolo inferiore, il quale avrà le seguenti dimensioni:

        larghezza: larghezza testo se inferiore alla larghezza della figura, larghezzafigura se caption troppo lunga
        altezza: pari al numero di righe in cui si divide il testo della caption

      Dopo essere riuscito a disegnare la cornice intorno alla figura, mi sono reso conto che non sono buono a passare certi parametri al comando caption, quindi ora sto battendo la strada della modifica del comando \caption.

      Consigli?

      Michele

    • #58998
      Up
      0
      Down
      ::

      Consigli?

      Prima di tutto di non usare \edef\CAP{#3} né \edef\LAB{#4}, vai solo in cerca di problemi: \def è perfettamente adatto allo scopo.

      Non vedo grandi problemi; la definizione di \@makecaption in article.cls è
      `\long\def\@makecaption#1#2{%
      \vskip\abovecaptionskip
      \sbox\@tempboxa{#1: #2}%
      \ifdim \wd\@tempboxa >\hsize
      #1: #2\par
      \else
      \global \@minipagefalse
      \hb@xt@\hsize{\hfil\box\@tempboxa\hfil}%

      \fi
      \vskip\belowcaptionskip}`
      A te serve la parte che ho messo in evidenza in blu (dove #1 è \fnum@figure); direi che puoi fare qualcosa del genere:
      `\sbox\@captionbox{\fnum@figure: \CAP}%
      \ifdim\wd\@captionbox>X
      \sbox\@captionbox{\parbox{X}\fnumfigure: \CAP}}%
      \fi`
      A questo punto hai a disposizione \ht\@captionbox e \dp\@captionbox per decidere quanto alto fare il tuo rettangolo inferiore. Con X denoto una dimensione che devi decidere tu: la massima larghezza della didascalia. Poi userai qualche magia di TiKZ per inserire \box\@captionbox dove ti pare.

      Il codice completo dovrà andare tra \makeatletter e \makeatother e dopo \makeatletter dovrai inserire anche \newbox\@captionbox.

      Ciao
      Enrico

      PS: ho leggermente modificato il tuo messaggio, se vuoi sapere dove, cerca \ddt. 😉

    • #58999
      Up
      0
      Down
      ::

      PS: ho leggermente modificato il tuo messaggio, se vuoi sapere dove, cerca \ddt. 😉

      Ops… scusate la volgarità…

      Vi farò sapere come risolverò il mio problema.

      Michele

    • #59000
      Up
      0
      Down
      ::


      Mi sono accorto che cambiando l’ambiente figure perdo il controllo delle opzioni [htpb].

      Mi sbaglio?

      Come faccio a recuperarle?

      Michele

    • #59001
      Up
      0
      Down
      ::

      Mi sono accorto che cambiando l’ambiente figure perdo il controllo delle opzioni [htpb].

      `\newenvironment{tikzgraphic}[5][tpb]
      {\@float{figure}[#1] …}
      {… \end@float}`
      Darai l’argomento (facoltativo) di posizione subito dopo \begin{tikzgraphic}.

      Ciao
      Enrico

    • #59002
      Up
      0
      Down
      ::


      Ciao,

      ecco la soluzione che ho trovato
      `
      %%%%%%%%%%%%%%%%
      % FLOAT FIGURE %
      %%%%%%%%%%%%%%%%
      %\def\StarTrekFontScreen{\setromanfont{SWISS 911 UCm BT}}

      \newlength\@figureWidth
      %\show\fnum@figure

      \newlength\@captionHeight
      %\show\@captionHeight

      \newenvironment*{tikzgraphic}[5]{%
      % #1 = h t p oppure b
      % #2 = total picture width(cm)
      % #3 = picture name
      % #4 = caption
      % #5 = label
      \@float{figure}[#1]
      \centering
      \def\@CAP{#4}
      \def\@LAB{#5}

      \begin{tikzpicture}[remember picture]
      \def\@Ydist{1.5ex}
      \def\@Xdist{1ex}
      \def\@YH{5ex}
      \def\@topHeight{.4cm}
      \def\@bigRadius{.5cm}
      \def\@smallRadius{.1cm}

      \pgfmathsetlength{\@figureWidth}{(#2-(2*(\@Xdist+\@YH)))}
      \node[inner sep=-\pgflinewidth/2] (figure) at (0,0){\includegraphics[width=\@figureWidth]{#3}};

      \advance \c@figure by 1

      \node[minimum width = \@figureWidth,
      anchor = north west,
      fill = \mycolor,
      draw = \mycolor,
      inner xsep = 1ex,
      inner ysep = 1ex] (caption) at ($(figure.south west)+(0,-\@Ydist)$)
      {\begin{minipage}{\@figureWidth-2ex}
      {\StarTrekFontScreen\Large \fnum@figure}

      {\normalsize #4}
      \end{minipage}};

      \getheightofnode{\@captionHeight}{caption}

      \node[anchor = south,
      minimum width = \@figureWidth,
      minimum height = \@topHeight,
      fill = \mycolor,
      draw = \mycolor] (top) at ($(figure.north)+(0,\@Ydist)$){};

      \foreach \sign/\loc in {+/east,-/west}{
      \coordinate (E\loc) at ($(caption.south \loc)+(\sign\@Xdist,0)$);
      \coordinate (F\loc) at ($(E\loc)+(0,\@captionHeight)$);
      \coordinate (H\loc) at ($(top.north \loc)+(\sign\@Xdist,0)$);
      \coordinate (G\loc) at ($(top.south \loc)+(\sign\@Xdist,0)$);
      \fill[HEAD] (E\loc)arc[radius=\@bigRadius,start angle=-90,delta angle=\sign90]–
      ($(H\loc)+(\sign\@bigRadius,-\@bigRadius)$)
      arc[radius=\@bigRadius,start angle={90-\sign 90},delta angle=\sign90]–
      (G\loc)
      arc[radius=\@smallRadius,start angle=90,delta angle=-\sign90]–
      ($(F\loc)+(\sign\@smallRadius,\@smallRadius)$)
      arc[radius=\@smallRadius,start angle={90-\sign 90},delta angle=-\sign90]–
      cycle;}
      }{\end{tikzpicture}
      \caption{\@CAP}\label{\@LAB}\end@float}

      %%%%%%%%%%%
      % CAPTION %
      %%%%%%%%%%%
      \long\def\@makecaption#1#2{%
      \advance \c@figure by -1
      }
      `

      Codice da far girare con XeLaTeX o LuaLaTeX oppure togiere la riga in cui si definisce un font che ho installato sul mio OS.

      L’idea è questa…

      Praticamente ho imbrogliato il comando caption perché scrivo la didascalia come nodo nell’ambiente tikzpicture dove nelle righe precedendi faccio avanzare il counter \c@figure
      per mettere il numero giusto(altrimenti LaTeX stamperebbe tutti i numeri meno uno).

      Il comando \@makecaption invece lo svuoto completamente, lasciando comunque due input, e lo sostituisco con una sottrazione di uno del counter \c@figure.

      Il risultato si può vedere qui sotto

      Che ne dite? avreste affrontato il problema in modo diverso?

      Ora l’ulteriore passo è adattare il tutto, magari creando ambienti apposta, a tabelle, figure create con tikz e pgfplots e la cosa più difficile(immagino) adattarlo a delle subfigure create con il pacchetto subfig.

      Michele

    • #59003
      Up
      0
      Down
      ::


      Qualcuno mi può scrivere la definizione del comando \caption o dirmi dove lo trovo?

      Grazie

      Michele

    • #59004
      OldClaudio
      Partecipante
        Up
        0
        Down
        ::


        Michele, hai provato a cercare la stringa \caption nei file contenuti nella cartella …/tex/late/base/ della tua distribuzione?

        Avrai non solo la risposta ma anche l’imbarazzo della scelta; ricordati anche che \probabilmente \caption non ti serve a niente ma devi cercar \@makecaption o \@makescaption (c’è una s di differenza), perché in effetti sono queste due macro che scrivono la didascalia; la seconda è presente solo in alcune classi e serve per eseguire davvero \caption* che, così asteriscato, nonsi trova nelle classi standard.

    Visualizzazione 8 filoni di risposte
    • Devi essere connesso per rispondere a questo topic.

    Go to top