Sie sind hier

scrlayer-notecolumn Codevorschlag: Notizspalte in eine andere Umbrechen

Ich bin ein großer Fan vom Paket scrlayer-notecolumn und ich glaube eine interessante Erweiterung des Pakets wäre die Möglichkeit eine Notizspalte in eine andere auf derselben Seite umzubrechen.

Ich hab etwas mit dem Code experimentiert und würde eine Idee vorschlagen mit der man das tun könnte. Im Endeffekt nehme ich schlichtweg die Definition von \slnc@processnotes und füge die Möglichkeit ein, den restlichen Text der derzeitigen Notizspalte in eine andere zu speichern. Zusätzlich definiere ich den Befehl \ConnectMargins der als erstes Argument die Hauptnotizspalte nimmt und als zweites eine Liste der weiteren Notizebenen. Dazu noch ein Hilfsbefehl und es funktioniert mal relativ gut.
(Der Code ist leider länger weil ich die gesamte Definition von \slnc@processnotes kopieren musste. Der einzige Unterschied ist aber am Ende. Hab auch versucht den neuen Code an den Stil des restlichen Anzupassen.)

% !TEX encoding = UTF-8 Unicode
\documentclass[ngerman]{scrartcl}
 
\usepackage{babel}
\usepackage{scrlayer-notecolumn}
\usepackage{blindtext}
 
\begin{document}
 
\makeatletter
 
\newcommand \slnc@save@note@to{}
 
%% Fuege optionales Argument ein
  \renewcommand*{\slnc@processnotes}[2][]{%
%    \end{macrocode}
% Read as long notes from the notes file until the number at \#2 of
% \Macro{slnc@note} in the file is greater than \Counter{slncpage}. Put all
% these to the corresponding unprocessed list.
%    \begin{macrocode}
    \begingroup
      \slnc@readnotes{\value{slncpage}}%
%    \end{macrocode}
% Process the unprocessed list of the current note column
%    \begin{macrocode}
      \expandafter\let\expandafter\reserved@a
      \csname slnc@#2@unprocessed\endcsname
      \expandafter\global
      \expandafter\let\csname slnc@#2@unprocessed\endcsname\@empty
      \def\slnc@notesyncfonttest##1{%
        \ifhmode
          \PackageError{scrlayer-notecolumn}{%
            illegal font setting for `notecolumn.##1'%
          }{%
            Current setting of font for `notecolumn.##1' switches
            from\MessageBreak
            vertical mode to horizontal mode. This is
            illegal!\MessageBreak
            You have to change the font setting to fix
            this.\MessageBreak
            If you'll continue vertical alignment of notes may fail%
          }%
          \par\vskip-\dimexpr \baselineskip+\parskip\relax
        \fi
      }%
      \long\def\slnc@note##1##2##3##4{%
%<trace>        \typeout{TRACE (slnc): ##2<=\theslncpage?}%
        \ifnum ##2>\value{slncpage}\relax
%<trace>          \typeout{TRACE (slnc): no: unprocess note}%
          \expandafter\g@addto@macro\csname slnc@#2@unprocessed\endcsname{%
            \slnc@note{##1}{##2}{##3}{##4}%
          }%
        \else
          \ifnum ##2<\value{slncpage}\relax
            \PackageWarning{scrlayer-notecolumn}{note of type `#2' delayed}%
          \fi
          \boxmaxdepth\maxdepth
          \expandafter\setbox\csname slnc@#2@box\endcsname\vbox{%
            \expandafter\hsize\csname slnc@#2@width\endcsname
            \normalfont\normalsize
%    \end{macrocode}
% \changes{v0.2.3085}{2019/02/14}{using colour stack if available}%^^A
% If a color stack is available we switch to it before changing the font. So a
% color definition inside the font would overwrite every color change inside
% the column! But if we don't have a color stack, color switching is not
% permitted!
%    \begin{macrocode}
            \slnc@switchcolorstack{#2}%
            {%
              \usekomafont{notecolumn.#2}{%
                \slnc@notesyncfonttest{#2}%
                \expandafter\ifvoid\csname slnc@#2@box\endcsname
                  \expandafter\setbox\csname slnc@#2@box\endcsname\vbox{%
                    \kern\dimexpr\topskip-\baselineskip\relax
                  }%
                \fi
%    \end{macrocode}
% \changes{v0.1}{2015/10/07}{ready for renaming \cs{pdfpageheight} in
%   luaTeX}%^^A
% From lua\TeX~0.80.1 \cs{pdfpageheight} will be renamed into
% \cs{pageheight}. So we have to do an extra test for the new primitive.
%    \begin{macrocode}
                \scr@ifundefinedorrelax{pdfpageheight}{%
                  \scr@ifundefinedorrelax{pageheight}{%
                    \@tempdima=\paperheight
                  }{%
                    \@tempdima=\pageheight
                  }%
                }{%
                  \@tempdima=\pdfpageheight
                }%
                \@tempdima=\dimexpr \@tempdima-##3sp
                                    -1in-\topmargin
                                    -\headheight-\headsep
                                    -\baselineskip
                           \relax
                \@tempdimb=\dimexpr \expandafter\ht\csname slnc@#2@box\endcsname
                                   +\expandafter\dp\csname slnc@#2@box\endcsname
                           \relax
                \typeout{Soll: \the\@tempdima^^JIst: \space\the\@tempdimb}%
                \ifdim\@tempdima<\@tempdimb
%<*trace>
                  \PackageInfo{scrlayer-notecolumn}{%
                    Note moved down from\MessageBreak
                    \the\@tempdima\space to \the\@tempdimb\MessageBreak
                    at note box `#2'
                  }%
%</trace>
                \else
                  \ifdim\@tempdima>\@tempdimb
%<*trace>
                    \PackageInfo{scrlayer-notecolumn}{%
                      Adding vertical white space from\MessageBreak
                      \the\@tempdimb\space to \the\@tempdima\MessageBreak
                      into note box `#2'
                    }%
%</trace> 
                    \expandafter\setbox\csname slnc@#2@box\endcsname
                    \vbox {%
                      \expandafter\unvbox\csname slnc@#2@box\endcsname
                      \kern\dimexpr\@tempdima-\@tempdimb\relax
                    }%
                  \fi
                \fi
                \expandafter\ifvoid\expandafter\csname slnc@#2@box\endcsname
                \else
                  \@tempdima\dimexpr
                              \dp\strutbox
                              -\dp\csname slnc@#2@box\endcsname
                            \relax
                  \expandafter\unvbox\csname slnc@#2@box\endcsname
                  \ifdim\@tempdima>\z@ \kern\@tempdima\fi
                \fi
%    \end{macrocode}
% \changes{v0.1.2582}{2017/02/08}{restore several commands}%^^A
% Some commands have to be restored when processing the note.
%    \begin{macrocode}
                \slnc@restoreinnote
                \strut\ignorespaces ##4\par
              }%
            }%
          }%
        \fi
      }%
      \def\slnc@sync##1##2##3##4{%
        \ifnum ##2>\value{slncpage}\relax
          \expandafter\g@addto@macro\csname slnc@#2@unprocessed\endcsname{%
            \slnc@sync{##1}{##2}{##3}{}%
          }%
        \else
          \if@filesw
            \expandafter\setbox\csname slnc@#2@box\endcsname\vbox{%
              \expandafter\unvbox\csname slnc@#2@box\endcsname
              \scr@savepos
              \protected@write\@auxout{}{%
                \string\newlabel{notecolumn.##1.##3.syncnote.label}{%
                  {%
                    \noexpand\number\scr@lastypos
                  }{\thepage}%
                }%
              }%
            }%
          \fi
        \fi
      }%
      \reserved@a
      \expandafter\ifvoid\csname slnc@#2@box\endcsname
%<*trace>
        \PackageInfo{scrlayer-notecolumn}{Note box `#2' empty}%
%</trace>
      \else
        \ifdim \dimexpr \expandafter\ht\csname slnc@#2@box\endcsname
                       +\expandafter\dp\csname slnc@#2@box\endcsname
               \relax >\textheight\relax
%<*trace>
          \PackageInfo{scrlayer-notecolumn}{Split note box `#2'}%
%</trace>
          \splittopskip\topskip
          \splitmaxdepth\baselineskip
%    \end{macrocode}
% Bring back the colours:
% \changes{v0.2.3085}{2019/02/14}{\cs{slnc@switchcolorstack} added}%^^A
%    \begin{macrocode}
          \usekomafont{notecolumn.#2}{%
            \expandafter\vsplit\csname slnc@#2@box\endcsname to
            \textheight\relax
          }%
          \expandafter\ifvoid\csname slnc@#2@box\endcsname
          \else
            \expandafter\setbox\csname slnc@#2@box\endcsname\vbox{%
              \slnc@switchcolorstack{#2}%
              \expandafter\unvbox\csname slnc@#2@box\endcsname
            }%
          \fi
        \else
%<*trace>
          \PackageInfo{scrlayer-notecolumn}{Flush note box `#2'}%
%</trace>
%    \end{macrocode}
% Bring back the colours:
% \changes{v0.2.3085}{2019/02/14}{\cs{slnc@switchcolorstack} added}%^^A
%    \begin{macrocode}
          \usekomafont{notecolumn.#2}{%
            \slnc@switchcolorstack{#2}%
            \expandafter\box\csname slnc@#2@box\endcsname%
          }%
        \fi
      \fi
%% -------- Neuer Code hier ----------
%% Speichere optionales Argument
      \def\slnc@save@note@to{#1}%
%% Wenn leer: Nimm derzeitge Notizspalte
      \ifx\slnc@save@note@to\@empty\relax
        \def\slnc@save@note@to{#2}%
      \fi
%% Speichere restlichen Text in \slnc@save@note@to
      \expandafter\global
      \expandafter\setbox\csname slnc@\slnc@save@note@to @box\expandafter\endcsname
      \expandafter\box\csname slnc@#2@box\endcsname
    \endgroup
  }
 
\newcommand\slnc@processnotesTo [2]
  {%
    \ModifyLayer%
      [%
        contents = {\slnc@processnotes [#2] {#1}}%
      ]%
    {notecolumn.#1}%
  }
 
\newcommand\ConnectMargins[2]
  {%
    \def\slnc@main@layer{#1}%
    \def\slnc@to@layer{}%
    \scr@trim@spaces\slnc@main@layer
%% Gehe durch die Notizspalten
%% Stelle sicher, dass die letzte Notizspalte wieder in die erste hineinspeichert wird.
    \@for \slnc@to@layer :=#2,#1\do {%
%   
      \scr@trim@spaces\slnc@to@layer
% 
      \expandafter\expandafter\expandafter%
      \slnc@processnotesTo%
      \expandafter\expandafter\expandafter%
      {\expandafter\slnc@main@layer\expandafter}%
      \expandafter{\slnc@to@layer}%
%      
      \let \slnc@main@layer \slnc@to@layer%
    }%
  }
 
\DeclareNoteColumn[position=2cm]{test}
\DeclareNoteColumn[position=10cm]{test2}
 
\ConnectMargins{marginpar}{test,test2}
 
\null\makenote{\blindtext\blindtext\blindtext}
 
\end{document}

Das einzige was ich nicht wirklich geschafft habe, ist sicherzustellen, dass die Notizspalten in der richtigen Reihenfolge ausgegeben werden (man muss natürlich zuerst "marginpar", dann "test" dann "test2" ausgeben), aber da kenne ich mich leider nicht genug mit dem Code aus um das sicherzustellen.

Hoffe es ist verständlich und glaube dass das ein guter Zusatz zum Paket ist. Es ist wahrscheinlich der einfachste Weg Notizspalten zu basteln, die um den Haupttext herumgehen.

Mit freundlichen Grüßen,
Ben

forum: 
Bild von Markus Kohm

Den Code müsste ich mir erst noch näher anschauen. Allerdings wäre es mir lieber, wenn das jemand als Third-Party-Paket realisieren würde. scrlayer-notecolumn ist explizit als proof of concept veröffentlicht, bei dem es darum geht, was man mit dem Ebenenmodell von scrlayer so alles anstellen kann.

BTW: Ich würde nicht den Rest einer Spalte in eine andere schreiben. Stattdessen würde ich eine Spalte eher als Liste von Startpunkten + Höhen definieren. Die Breite darf ja in einem solchen Fall nicht variieren, weil ein einmal umbrochener Absatz nicht mehr (sauber) neu auf eine andere Breite umbrochen werden kann. Wie dann allerdings Synchronisationspunkte zu interpretieren sind, ist mir auch nicht so ganz klar. Da müsste man sich erst einmal Gedanken drüber machen.

Ah, ich dachte das Paket ist nur (für vielleicht längere zeit) temporär ein proof of concept und dann irgendwann die beta-Phase verlässt.

Das ein schon umgebrochener Absatz nicht wirklich an eine neue Seite angepasst wird, daran habe ich gar nicht gedacht. Aber stimmt, wenn ich die width der Testspalten ändere, dann sehe ich dass es keine Änderung gibt. Was ich mir nicht ganz vorstellen kann (weil ich wohl auch mich nicht gut genug auskenne) ist die Liste von Startpunkten + Höhen. Ist das so etwas wie \parshape wo ich den Text in die richtige Form bringe und dann umbreche und verschiebe? Oder ist was anderes gemeint?

Bild von Markus Kohm

Nun, bisher ist eine Spalte definiert durch einen Abstand vom linken Rand und eine Breite definiert. Man könnte aber natürlich statt nur einem Abstand vom linken Rand und nur einer Breite auch mehrere davon definieren. Wenn dann bei der Ausgabe in die erste davon das Ende erreicht ist, kann man den Rest davon in einer anderen ausgeben. Das ist übrigens so ähnlich wie LaTeX beim zweispaltigen Satz arbeitet. Und natürlich ist nicht zwingend, dass eine Spalte immer mit demselben Abstand von oben beginnt und dieselbe Höhe hat. Verallgemeinert könnte man also eine Liste von Startpunkten + Höhe zur Definition einer (über die ganze Seite verteilten) Spalte verwenden. Breite gäbe es jedoch aus den genannten Gründen für eine Spalte nur eine.

Klingt gut und nach einem Projekt für die nächsten Monate. Werde mal versuchen mit einzulesen und zu experimentieren.

Comments for "scrlayer-notecolumn Codevorschlag: Notizspalte in eine andere Umbrechen" abonnieren