cmhughes / latexindent.pl

Perl script to add indentation (leading horizontal space) to LaTeX files. It can modify line breaks before, during and after code blocks; it can perform text wrapping and paragraph line break removal. It can also perform string-based and regex-based substitutions/replacements. The script is customisable through its YAML interface.
GNU General Public License v3.0
864 stars 84 forks source link

how to format `dtx` files? #513

Closed Cube707 closed 6 months ago

Cube707 commented 6 months ago

This is a very heavy feature-request, so feel free to tell me it's out of scope šŸ˜„
But if this is of interes to you I would be happy to assist in getting this to work.

When creating LaTeX packages or classes the source-code and documentation is usually written in a single file of format dtx. This file contains two layers of LaTeX code, the source as expected and the documentation inside comments.

I would like to use latexindent to help me keep a consistent format, but I cant really get it to run properly. I would also argue that this is a common requirement in the LaTeX community and it might make sens to create a solution that can be included in the documentation or build directly into the script, if this is of interest to you.

what are dtx files

The filetype mixes package source-code and documentation in a single file. It can be processed using different standard utilities to produce both the class/package file and a pdf documenting it.

Calling the docstrip utility on the file will stip all comments (and therefore the documentation), leaving only the bare source-code.

Calling pdflatex on the file will process it into a pdf with the proceeding % beeing removed, printing the documentation and all source-code being contained inside macrocode blocks.

original code

Note that lines prefixed with % are not commented out but are valid LaTeX-code.

% \iffalse
%<*driver> ^^A ---------- documentation driver -----------------------------------------
\ProvidesFile{class.dtx}
\documentclass{ltxdoc}
\begin{document}
\DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
% ^^A ---------- document body -----------------------------------------
% \title{A \LaTeX\ class}
% \maketitle
%
% \section{Introduction}
% This is just an example.
%
% \section{Class commands}
% You can use the following options:
%
% \begin{description}
% \item[foo] first command with long paragraph
% \item[bar] second command
% \end{description}
%
% \section{Implementation}
%    \begin{macrocode}
%<*class>
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{HsH-standalone}[2024-01-29 my cool class]
%    \end{macrocode}
%
% \subsection{Implement the commands}
%
% \begin{macro}{\foo}
% this is an example macro.
%    \begin{macrocode}
\def\foo{foo}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\bar}
% this is an example macro.
%    \begin{macrocode}
\def\bar{bar}
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
%<*class>
%    \end{macrocode}
\endinput

actual/given output

running latexindent on the file only formats the not-commented parts (as is expected)

desired output

something similar to this:

% \iffalse
%<*driver> ^^A ---------- documentation driver -----------------------------------------
\ProvidesFile{class.dtx}
\documentclass{ltxdoc}
\begin{document}
\DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
% ^^A ---------- document body -----------------------------------------
%
%\title{A \LaTeX\ class}
%\maketitle
%
%\section{Introduction}
%   This is just an example.
%
%\section{Class commands}
%  You can use the following options:
%
%  \begin{description}
%    \item[foo] first command with
%          long paragraph
%    \item[bar] second command
%  \end{description}
%
%\section{Implementation}
%  \begin{macrocode}
%<*class>
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{HsH-standalone}[2024-01-29 my cool class]
%  \end{macrocode}
%
%  \subsection{Implement the commands}
%
%    \begin{macro}{\foo}
%    this is an example macro.
%    \begin{macrocode}
\def\foo{
  foo
}
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macro}{\bar}
%    this is an example macro.
%    \begin{macrocode}
\def\bar{
  bar
}
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macrocode}
%<*class>
%    \end{macrocode}
\endinput

anything else

cmhughes commented 6 months ago

Thanks for this.

Using the following settings

cube707.yaml

defaultIndent: "  "

specialBeginEnd:
  #
  # store 
  #     ^^A ....
  # as verbatim
  #
  dtxComments:
    begin: \^\^A
    body: [^\n]*?
    end: ''
    lookForThis: verbatim
  #
  # store 
  #     <.*?>
  # as verbatim
  #
  dtxXML:
    begin: \<
    body: [^>]*?
    end: \>
    lookForThis: verbatim

# 
# polyswitch work
#
modifyLineBreaks:
  mandatoryArguments:
    foo:
      MandArgBodyStartsOnOwnLine: 1       # -1,0,1,2,3,4
      RCuBStartsOnOwnLine: 1              # -1,0,1,2,3,4
    bar:
      MandArgBodyStartsOnOwnLine: 1       # -1,0,1,2,3,4
      RCuBStartsOnOwnLine: 1              # -1,0,1,2,3,4

replacements:
  #
  # BEFORE indentation
  #
  # change
  #
  #   % \iffalse
  #
  # into
  #
  #   \iffalse%TOBEREMOVED
  - 
    substitution: |-
      s/^%(.*?)$/$1%TOBEREMOVED/mg
    when: before
  #
  # AFTER indentation
  #
  # change
  #
  #   \iffalse%TOBEREMOVED
  #
  # back into
  #
  #   % \iffalse
  - 
    substitution: |-
      s/^(.*?)%TOBEREMOVED$/% $1/mg
    when: after
  #
  # change
  #
  #   %     <>
  #
  # into
  #
  #   %<>
  - 
    substitution: |-
      s/^%\h*\</%</mg
    when: after
  #
  # change, for example
  #
  #  %<*class>
  #     \NeedsTeXFormat{LaTeX2e}
  #     \ProvidesClass{HsH-standalone}[2024-01-29 my cool class]
  #  % \end{macrocode}
  #
  # into
  #
  #  %<*class>
  #  \NeedsTeXFormat{LaTeX2e}
  #  \ProvidesClass{HsH-standalone}[2024-01-29 my cool class]
  #  % \end{macrocode}
  - 
    substitution: |-
      s/^(%.*?\R)((?:[^%].*?$)+?\R)(%)/
      my $begin =  $1;
      my $middle = $2;
      my $end    = $3;
      # remove leading space from first line of $middle
      $middle =~ s|^(\h*)||s;
      my $leadingSpace = ($1?$1:q());
      $middle =~ s|^$leadingSpace||mg;
      $begin.$middle.$end;/sgmxe
    when: after

and calling

latexindent.pl -r -m -l cube707.yaml myfile.dtx

gives the following

% \iffalse
%<*driver> ^^A ---------- documentation driver -----------------------------------------
\ProvidesFile{class.dtx}
\documentclass{ltxdoc}
\begin{document}
\DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
% ^^A ---------- document body -----------------------------------------
% \title{A \LaTeX\ class}
% \maketitle
% 
% \section{Introduction}
% This is just an example.
% 
% \section{Class commands}
% You can use the following options:
% 
% \begin{description}
%   \item[foo] first command with long paragraph
%   \item[bar] second command
% \end{description}
% 
% \section{Implementation}
% \begin{macrocode}
%<*class>
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{HsH-standalone}[2024-01-29 my cool class]
% \end{macrocode}
% 
% \subsection{Implement the commands}
% 
% \begin{macro}{\foo}
%   this is an example macro.
%   \begin{macrocode}
\def\foo{
  foo
}
%   \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\bar}
%   this is an example macro.
%   \begin{macrocode}
\def\bar{
  bar
}
%   \end{macrocode}
% \end{macro}
% 
% \begin{macrocode}
%<*class>
% \end{macrocode}
\endinput

I hope it as you would like :)

Cube707 commented 6 months ago

Thank you very much for this quick response.

I added the following substitution at the end, as I just learned that \end{macrocode} has a hardcoded requirement to have foure leading spaces -_-

  # the \begin{macrocode} and \end{macrocode} need to be indented by exactly four spaces
  -
    substitution: |-
      s/^% *\\(begin|end)\{macrocode\}/%    \\$1\{macrocode\}/mg
    when: after
Cube707 commented 6 months ago

Running you config on the full document has opened some more problems.

The following code illustrates some of them:

% \section{Implementation}
%
% \subsection{Executind default options}
% We have some default options that need executing:
%    \begin{macrocode}
\FamilyExecuteOptions{HsH}{%
%<*!standalone>
  fontsize=11pt,
%<article>  parskip=never+,
%<report>  parskip=half+,
  headheight=2.15\baselineskip,
%</!standalone>
%<*article|report>
  toc=listof,
  toc=bibliography,
%</article|report>
  fontfamily=sans-serif,
  linespacing=single,
  faculty=none,
%<*standalone>
  margin=0.25cm,
  multi=tikzpicture,
  multi=circuitikz,
%</standalone>
}
%    \end{macrocode}

running latexindent -r -m -l cube707.yaml testing.dtx in it results in:

% \section{Implementation}
% 
% \subsection{Executind default options}
% We have some default options that need executing:
% \begin{macrocode}
\FamilyExecuteOptions{HsH}{%
%<*!standalone>
    fontsize=11pt,
%<article>  parskip=never+,
%<report>  parskip=half+,
headheight=2.15\baselineskip,
%</!standalone>
%<*article|report>
toc=listof,
toc=bibliography,
%</article|report>
    fontfamily=sans-serif,
    linespacing=single,
    faculty=none,
%<*standalone>
margin=0.25cm,
multi=tikzpicture,
multi=circuitikz,
%</standalone>
  }
% \end{macrocode}

I start leaning heavily towards splitting the whole thing into two. One run to only format the not-commented lines and one run to format only the commented lines with comment characters removed (and some magic to get Docstrip guards to work). This would allow for more clear and easier separation of settings between the two?

What do you think?

Cube707 commented 6 months ago

also this is the full file if you want to get a feel for it: https://lab.it.hs-hannover.de/qxx-tul-u1/latex-template-hsh/-/blob/b7d5c8ae9f9e3381fd3398873191d2d5fbec61dc/src/HsH-classes.dtx

cmhughes commented 6 months ago

Please give desired output and I'll try to help.

On Wed, 31 Jan 2024, 13:18 Jan Wille, @.***> wrote:

also this is the full file if you want to get a fell for it: https://lab.it.hs-hannover.de/qxx-tul-u1/latex-template-hsh/-/blob/b7d5c8ae9f9e3381fd3398873191d2d5fbec61dc/src/HsH-classes.dtx

ā€” Reply to this email directly, view it on GitHub https://github.com/cmhughes/latexindent.pl/issues/513#issuecomment-1919088127, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAQ7CYFIEGWKU442VRAG6Z3YRJAC3AVCNFSM6AAAAABCRUJUTOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMJZGA4DQMJSG4 . You are receiving this because you commented.Message ID: @.***>

Cube707 commented 6 months ago

And feel free to tell me to stop bothering you with this. Its just that I am quite surprised that I can't find much regarding this problem when pretty much every package author has a dtx file and would benefit from having a convenient way to get it prettyfied

Cube707 commented 6 months ago

Please give desired output and I'll try to help.

as running latexindent on this simplified, striped version (with defaultIndent:' '):

\FamilyExecuteOptions{HsH}{%
fontsize=11pt,
parskip=never+,
}

will result in

\FamilyExecuteOptions{HsH}{%
  fontsize=11pt,
  parskip=never+,
}

I would like the output to be

% \section{Implementation}
%
% \subsection{Executind default options}
% We have some default options that need executing:
%    \begin{macrocode}
\FamilyExecuteOptions{HsH}{%
%<*!standalone>
  fontsize=11pt,
%<article>  parskip=never+,
%<report>  parskip=half+,
  headheight=2.15\baselineskip,
%</!standalone>
%<*article|report>
  toc=listof,
  toc=bibliography,
%</article|report>
  fontfamily=sans-serif,
  linespacing=single,
  faculty=none,
%<*standalone>
  margin=0.25cm,
  multi=tikzpicture,
  multi=circuitikz,
%</standalone>
}
%    \end{macrocode}

note that the indentation after %<article> should match the rest of the block, if possible

cmhughes commented 6 months ago

Are you sure these tags are balanced correctly?

On Wed, 31 Jan 2024, 13:28 Jan Wille, @.***> wrote:

Please give desired output and I'll try to help.

as running latexindent on this simplified, striped version (with defaultIndent:' '):

\FamilyExecuteOptions{HsH}{% fontsize=11pt, parskip=never+, }

will result in

\FamilyExecuteOptions{HsH}{% fontsize=11pt, parskip=never+, }

I would like the output to be

% \section{Implementation}%% \subsection{Executind default options}% We have some default options that need executing:% \begin{macrocode} \FamilyExecuteOptions{HsH}{%%<!standalone> fontsize=11pt,%

parskip=never+,% parskip=half+, headheight=2.15\baselineskip,%</!standalone>%<article|report> toc=listof, toc=bibliography,%</article|report> fontfamily=sans-serif, linespacing=single, faculty=none,%<*standalone> margin=0.25cm, multi=tikzpicture, multi=circuitikz,% }% \end{macrocode}

note that the indentation after %

Cube707 commented 6 months ago

yes, processing it through docstrip produces the expected results.

%<*TAG> begins a multiline block, %</TAG> ends it.

%<TAG> is a single line block that is ende by \n

this means that lines 7-12 will not be passed to the standalone ouput, but with line 9 only getting passed to the article output and line 10 only to report. Lines 13-14 are for both article and report, lines 17-19 are unguarded and therfor get passed always and lines 20-24 are only for standalone

cmhughes commented 6 months ago

Using the following

defaultIndent: "  "

specialBeginEnd:
  iffalse:
    begin: \\iffalse\R
    end: \\fi
  #
  # store 
  #     ^^A ....
  # as verbatim
  #
  dtxComments:
    begin: \^\^A
    body: [^\n]*?
    end: ''
    lookForThis: verbatim
  #
  # store 
  #     <.*?>
  # as verbatim
  #
  dtxXML:
    begin: \<
    body: [^>]*?
    end: \>
    lookForThis: verbatim

noAdditionalIndent:
  iffalse: 1
  macrocode: 1

# 
# polyswitch work
#
modifyLineBreaks:
  mandatoryArguments:
    foo:
      MandArgBodyStartsOnOwnLine: 1       # -1,0,1,2,3,4
      RCuBStartsOnOwnLine: 1              # -1,0,1,2,3,4
    bar:
      MandArgBodyStartsOnOwnLine: 1       # -1,0,1,2,3,4
      RCuBStartsOnOwnLine: 1              # -1,0,1,2,3,4

replacements:
  #
  # BEFORE indentation
  #
  # change
  #
  #   % \iffalse
  #
  # into
  #
  #   \iffalse%TOBEREMOVED
  - 
    substitution: |-
      s/^%(.*?)$/$1%TOBEREMOVED/mg
    when: before
  #
  # AFTER indentation
  #
  # change
  #
  #   \iffalse%TOBEREMOVED
  #
  # back into
  #
  #   % \iffalse
  - 
    substitution: |-
      s/^(.*?)%TOBEREMOVED$/% $1/mg
    when: after
  #
  # change
  #
  #   %     <>
  #
  # into
  #
  #   %<>
  - 
    substitution: |-
      s/^%\h*\</%</mg
    when: after
  #
  # change, for example
  #
  #  %<*class>
  #     \NeedsTeXFormat{LaTeX2e}
  #     \ProvidesClass{HsH-standalone}[2024-01-29 my cool class]
  #  % \end{macrocode}
  #
  # into
  #
  #  %<*class>
  #  \NeedsTeXFormat{LaTeX2e}
  #  \ProvidesClass{HsH-standalone}[2024-01-29 my cool class]
  #  % \end{macrocode}
  - 
    substitution: |-
      s@^                         # line begins with
        (%                        # %
          (?!                     # not followed by
            (?:                   # 
              (?:<[*a-zA-Z])      #   <[*a-zA-Z]
              |                   # OR
              (?:<\/[a-zA-Z]+\|)  #   </[a-zA-Z]|
            )                     # 
          )[^\n]*?\R              # anything except a new line
        )                         # 
        (                         # 
          (?:[^%].*?$)+?\R        # %
        )                         # 
        (%)@
      my $begin =  $1;
      my $middle = $2;
      my $end    = $3;
      # remove leading space from first line of $middle
      $middle =~ s|^(\h*)||s;
      my $leadingSpace = ($1?$1:q());
      $middle =~ s|^$leadingSpace||mg;
      $begin.$middle.$end;@sgmxe
    when: after

gives

% \section{Implementation}
% 
% \subsection{Executind default options}
% We have some default options that need executing:
% \begin{macrocode}
\FamilyExecuteOptions{HsH}{%
%<*!standalone>
  fontsize=11pt,
%<article>  parskip=never+,
%<report>  parskip=half+,
  headheight=2.15\baselineskip,
%</!standalone>
%<*article|report>
  toc=listof,
  toc=bibliography,
%</article|report>
  fontfamily=sans-serif,
  linespacing=single,
  faculty=none,
%<*standalone>
  margin=0.25cm,
  multi=tikzpicture,
  multi=circuitikz,
%</standalone>
}
% \end{macrocode}
Cube707 commented 6 months ago

thank you very much for this effort.

I tried to incorporate all this into one complete version, but couldn't it was to complicated for me.

However using your examples as inspiration I was able to get it mostly working in two separate passes. Using th two settings files dtxDoc.yaml and dtxSource.yaml

defaultIndent: "  "

indentRules:
  section: "  "
  subsection: "  "
indentAfterHeadings:
  section:
    indentAfterThisHeading: 1
    level: 1
  subsection:
    indentAfterThisHeading: 1
    level: 2

indentAfterItems:
  description: 1

specialBeginEnd:
  # ^^A .... as verbatim
  dtxComments:
    begin: \^\^A
    end: \n
    lookForThis: verbatim

  # %<.*?> as verbatim
  dostripMultilineGuards:
    begin: '%\<[*/]'
    end: '\>'
    lookForThis: verbatim

  # \iffalse .. \fi as verbatime
  iffalse:
    begin: \\iffalse
    end: \\fi
    lookForThis: verbatim

  # everything inside macrocode is verbatime,
  # gets formatted by the second pass
  macrocode:
    begin: \\begin\{macrocode\}
    end: \\end\{macrocode\}
    lookForThis: verbatim

  # the custom TBR marker shouldn't be touched
  toBeRemoved:
    begin: '%TBR'
    end: \n
    lookForThis: verbatim

replacements:
  # remove leading %
  - substitution: |-
      s/^%(?!<) ?(.*?)$/$1%TBR/mg
    when: before

  # put leading % back
  - substitution: |-
      s/^(.*?)% *?TBR$/% $1/mg
    when: after

  # the \begin{macrocode} and \end{macrocode} need to be indented by exactly four spaces
  - substitution: |-
      s/^% *\\(begin|end)\{macrocode\}/%    \\$1\{macrocode\}/mg
    when: after
defaultIndent: "  "

specialBeginEnd:
  # skip each line starting with %
  dxtDocLines:
    begin: ^%
    end: \n
    lookForThis: verbatim

  # the custom TBR marker shouldn't be touched
  ToBeRemoved:
    begin: '%TBR'
    end: \n
    lookForThis: verbatim

replacements:
  # move single-line guard to the end of the line
  - substitution: |-
      s/%(\<[^*\/]*?\>)(.*?)$/$2%TBR$1/mg
    when: before

  # put leading guard back
  - substitution: |-
      s/^(.*?)%TBR(.*?)$/%$2$1/mg
    when: after

  # remove leading space from all lines starting with %
  - substitution: |-
      s/^\h*%/%/mg
    when: after

This sucessfully formats the following testing.dxt by calling latexindent -r -l dtxDoc.yaml testing.dtx -w -s && latexindent -r -l dtxSource.yaml testing.dtx -w -s

% \iffalse
%<*driver> ^^A ---------- documentation driver --------------------------------
\ProvidesFile{class.dtx}
\documentclass{ltxdoc}
\begin{document}
\DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
% ^^A ---------- document body ------------------------------------------------
%\title{A \LaTeX\ class}
%  \maketitle
%
%     \section{Introduction}
%  This is just an example.
%
% \section{Class commands}
% You can use the following options:
%
% \begin{description}
% \item[foo] first command with long paragraph tha should be automatically brocken into multiple lines
% \item[bar] second command
%            with two destict lines
% \end{description}
%
% \section{Implementation}
%
%           Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec volutpat turpis sit amet dapibus facilisis. Duis mauris mi, scelerisque et.
%
%    \begin{macrocode}
%<*class>
 \NeedsTeXFormat{LaTeX2e}
         \ProvidesClass{HsH-standalone}[2024-01-29 my cool class]
%    \end{macrocode}
%
%    \subsection{Executind default options}
%    We have some default options that need executing:
%    \begin{macrocode}
\FamilyExecuteOptions{HsH}{%
%<*!standalone>
fontsize=11pt,
%<article>    parskip=never+,
%<report> parskip=half+,
  headheight=2.15\baselineskip,
%</!standalone>
%<*article|report>
toc=listof,
     toc=bibliography,
%</article|report>
  fontfamily=sans-serif,
 linespacing=single,
  faculty=none,
%<*standalone>
margin=0.25cm,
multi=tikzpicture,
multi=circuitikz,
%</standalone>
}
%    \end{macrocode}
%
% \subsection{Implement the commands}
%
%    \begin{macro}{\foo}
% this is an example macro.
%    \begin{macrocode}
   \def\foo{foo}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\bar}
% this is an example macro.
%    \begin{macrocode}
\def\bar{bar}
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
%<*class>
%    \end{macrocode}
\endinput
Cube707 commented 6 months ago

however I have some question:

is there really no better way to mark a line as "don't put any indentation"? Do I really have to pull the guards %<tag> back to the beginning via a replacement?

Do you see any way to get multiline support -m working? The \item and the Lorem ipsum lines could benefit from beeing split and this would work without the %, but fails with my replacement "hack". Any Ideas for this ?

cmhughes commented 6 months ago

If I used the following settings

defaultIndent: "  "

specialBeginEnd:
  iffalse:
    begin: \\iffalse\R
    end: \\fi
  #
  # store 
  #     ^^A ....
  # as verbatim
  #
  dtxComments:
    begin: \^\^A
    body: [^\n]*?
    end: ''
    lookForThis: verbatim
  #
  # store 
  #     <.*?>
  # as verbatim
  #
  dtxXML:
    begin: \<
    body: [^>]*?
    end: \>
    lookForThis: verbatim

noAdditionalIndent:
  iffalse: 1
  macrocode: 1

# 
# polyswitch work
#
modifyLineBreaks:
  mandatoryArguments:
    foo:
      MandArgBodyStartsOnOwnLine: 1       # -1,0,1,2,3,4
      RCuBStartsOnOwnLine: 1              # -1,0,1,2,3,4
    bar:
      MandArgBodyStartsOnOwnLine: 1       # -1,0,1,2,3,4
      RCuBStartsOnOwnLine: 1              # -1,0,1,2,3,4

replacements:
  #
  # BEFORE indentation
  #
  # change
  #
  #   % \iffalse
  #
  # into
  #
  #   \iffalse%TOBEREMOVED
  - 
    substitution: |-
      s/^%(.*?)$/$1%TOBEREMOVED/mg
    when: before
  #
  # AFTER indentation
  #
  # change
  #
  #   \iffalse%TOBEREMOVED
  #
  # back into
  #
  #   % \iffalse
  - 
    substitution: |-
      s/^(.*?)%TOBEREMOVED$/% $1/mg
    when: after
  #
  # change
  #
  #   %     <>
  #
  # into
  #
  #   %<>
  - 
    substitution: |-
      s/^%\h*\</%</mg
    when: after
  #
  # change, for example
  #
  #  %<*class>
  #     \NeedsTeXFormat{LaTeX2e}
  #     \ProvidesClass{HsH-standalone}[2024-01-29 my cool class]
  #  % \end{macrocode}
  #
  # into
  #
  #  %<*class>
  #  \NeedsTeXFormat{LaTeX2e}
  #  \ProvidesClass{HsH-standalone}[2024-01-29 my cool class]
  #  % \end{macrocode}
  - 
    substitution: |-
      s@^                         # line begins with
        (%                        # %
          (?!                     # not followed by
            (?:                   # 
              (?:<[*a-zA-Z])      #   <[*a-zA-Z]
              |                   # OR
              (?:<\/[a-zA-Z]+\|)  #   </[a-zA-Z]|
            )                     # 
          )[^\n]*?\R              # anything except a new line
        )                         # 
        (                         # 
          (?:[^%].*?$)+?\R        # %
        )                         # 
        (%)@
      my $begin =  $1;
      my $middle = $2;
      my $end    = $3;
      # remove leading space from first line of $middle
      $middle =~ s|^(\h*)||s;
      my $leadingSpace = ($1?$1:q());
      $middle =~ s|^$leadingSpace||mg;
      $begin.$middle.$end;@sgmxe
    when: after

on your most recent file then I receive

% \iffalse
%<*driver> ^^A ---------- documentation driver --------------------------------
\ProvidesFile{class.dtx}
\documentclass{ltxdoc}
\begin{document}
\DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
% ^^A ---------- document body ------------------------------------------------
% \title{A \LaTeX\ class}
% \maketitle
% 
% \section{Introduction}
% This is just an example.
% 
% \section{Class commands}
% You can use the following options:
% 
% \begin{description}
%   \item[foo] first command with long paragraph tha should be automatically brocken into multiple lines
%   \item[bar] second command
%         with two destict lines
% \end{description}
% 
% \section{Implementation}
% 
% Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec volutpat turpis sit amet dapibus facilisis. Duis mauris mi, scelerisque et.
% 
% \begin{macrocode}
%<*class>
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{HsH-standalone}[2024-01-29 my cool class]
% \end{macrocode}
% 
% \subsection{Executind default options}
% We have some default options that need executing:
% \begin{macrocode}
\FamilyExecuteOptions{HsH}{%
%<*!standalone>
  fontsize=11pt,
%<article>    parskip=never+,
%<report> parskip=half+,
  headheight=2.15\baselineskip,
%</!standalone>
%<*article|report>
  toc=listof,
  toc=bibliography,
%</article|report>
  fontfamily=sans-serif,
  linespacing=single,
  faculty=none,
%<*standalone>
  margin=0.25cm,
  multi=tikzpicture,
  multi=circuitikz,
%</standalone>
}
% \end{macrocode}
% 
% \subsection{Implement the commands}
% 
% \begin{macro}{\foo}
%   this is an example macro.
%   \begin{macrocode}
\def\foo{
  foo
}
%   \end{macrocode}
% \end{macro}
% 
% \begin{macro}{\bar}
%   this is an example macro.
%   \begin{macrocode}
\def\bar{
  bar
}
%   \end{macrocode}
% \end{macro}
% 
% \begin{macrocode}
%<*class>
% \end{macrocode}
\endinput

Is this what you want? If you're wanting to text wrap (?) please do be specific with what you're starting with, and what you'd like to receive.

Cube707 commented 5 months ago

Sorry for the long delay, I was on holliday.

I think we misunderstood each other somewhat. This request has always been about generall support for .dtx files, not getting a specific use case to work.

I wanted to get a understanding on the following:

And I wanted to know if there is interest to improve on this (I am willing to work on this if you are not intersted in working on that but would accept improvements in this regard). Should this only be in form of documentation and examples or is there interest to improve actual functionality and reduce/remove the limitations.

cmhughes commented 5 months ago

Thanks for this.

Please feel to take this on, I don't have capacity to do so at this time. Pull requests to develop, please.

On Fri, 1 Mar 2024, 19:54 Jan Wille, @.***> wrote:

Sorry for the long delay, I was on holliday.

I think we misunderstood each other somewhat. This request has always been about generall support for .dtx files, not getting a specific use case to work.

I wanted to get a understanding on the following:

  • Can dtx-file formatting be achieved? (we have shown it can be)
  • Can all configuration-options of latexindent be made to work on both the normal source as well as the documentation inside the comments? (we established it is possible and that it is helpful to use two separate config-files and two runs)
  • What limitations apply? (it seems to be that word-wrapping will not work)

And I wanted to know if there is interest to improve on this (I am willing to work on this if you are not intersted in working on that but would accept improvements in this regard). Should this only be in form of documentation and examples or is there interest to improve actual functionality and reduce/remove the limitations.

ā€” Reply to this email directly, view it on GitHub https://github.com/cmhughes/latexindent.pl/issues/513#issuecomment-1973822311, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAQ7CYFVS3Q5IP7GKQRYSGTYWDMGLAVCNFSM6AAAAABCRUJUTOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNZTHAZDEMZRGE . You are receiving this because you modified the open/close state.Message ID: @.***>