3

As you can see, this is similar to that quesion. However I think my problem has not been solved and then open this.

I'm using markdown package in my LaTeX document and it works well. However I find my tables always float to the top of my page after I add caption, just like that;

test1

So I have to disable the float property. I find the markdown.sty file:

sty

then find table label and put [htbp] after it. Then it works!

test2

Now I know where is the problem. However it is not a good solution indeed. Then I read user manual and find Table Renderer setting. It says:

2.3.1.21 Table Renderer

The \markdownRendererTable macro represents a table. This macro will only be produced, when the pipeTables option is enabled. The macro receives the parameters {⟨caption⟩}{⟨number of rows⟩}{⟨number of columns⟩} followed by {⟨alignments⟩} and then by {⟨row⟩} repeated ⟨number of rows⟩ times, where ⟨row⟩ is {⟨column⟩} repeated ⟨number of columns⟩ times, ⟨alignments⟩ is ⟨alignment⟩ repeated ⟨number of columns⟩ times, and ⟨alignment⟩ is one of the following......

LATEX Example Using a text editor, create a text document named document.tex with the following content:

\documentclass{article}
\usepackage[pipeTables, tableCaptions]{markdown}
\newcount\rowCounter
\newcount\columnCounter
\makeatletter
\def\processRow#1{%
  \columnCounter=1%
  \ifnum\rowCounter=0\relax
    As for the alignment,
  \else
    In row \the\rowCounter,
  \fi
  \processColumn#1
  \advance\rowCounter by 1\relax
  \ifnum\rowCounter>\rowTotal\relax
    \expandafter\@gobble
  \fi\processRow}%
\def\processColumn#1{%
  column number \the\columnCounter{}
  \ifnum\rowCounter=0\relax
    \if#1d{}has default alignment\fi
    \if#1l{}is left-aligned\fi
    \if#1c{}is centered\fi
    \if#1r{}is right-aligned\fi
  \else
    says \emph{#1}%
  \fi
  \advance\columnCounter by 1\relax
  \ifnum\columnCounter<\columnTotal\relax, \fi
  \ifnum\columnCounter=\columnTotal\relax, and \fi
  \ifnum\columnCounter>\columnTotal\relax
    .\expandafter\@gobble
  \fi\processColumn}%
\makeatother
\markdownSetup{
  renderers = {
    table = {%
      This is a table with caption \emph{#1} that is #3 colums wide
      and #2 rows long.
      \rowCounter=0%
      \def\rowTotal{#2}%
      \def\columnTotal{#3}%
      \processRow
    },
  },
}
\begin{document}
\begin{markdown}
| Right | Left | Default | Center |
|------:|:-----|---------|:------:|
|   12  |  12  |    12   |    12  |
|  123  |  123 |   123   |   123  |
|    1  |    1 |     1   |     1  |

: Demonstration of pipe table syntax \end{markdown} \end{document}

A PDF document named document.pdf should be produced and contain the following text:

This is a table with caption Demonstration of pipe table syntax that is 4 colums wide and 4 rows long. As for the alignment, column number 1 is right-aligned, column number 2 is left-aligned, column number 3 has default alignment, and column number 4 is centered. In row 1, column number 1 says Right, column number 2 says Left, column number 3 says Default, and column number 4 says Center. In row 2, column number 1 says 12, column number 2 says 12, column number 3 says 12, and column number 4 says 12. In row 3, column number 1 says 123, column number 2 says 123, column number 3 says 123, and column number 4 says 123. In row 4, column number 1 says 1, column number 2 says 1, column number 3 says 1, and column number 4 says 1.

Urr......I think my level of TeX is not sufficient to understand how it turn the table into a "mess" .

Then I tried copying codes in markdown.sty to my LaTeX file with \makeatletter command, but it failed.

It seems much more difficult than image renderer. To change the image renderer I just need to put below into my file:

\markdownSetup{                                     
  renderers = {    
    image = {\begin{figure}[htb]
      \centering
      \includegraphics[width = .9\linewidth]{#3}% 
      \ifx\empty#4\empty\else
        \caption{#4}\label{fig:#1}%
      \fi
    \end{figure}}
  }                                               
}

It is easy and clear...but I don't know how table renderer works. Maybe I need to write much more code to achieve that.

ps: here is a simple test file:

\documentclass{article}
\usepackage{markdown}
\markdownSetup{pipeTables = true}                   
\markdownSetup{tableCaptions = true}
\usepackage{fancyhdr}
\pagestyle{fancy}
\fancyhf{}
\begin{document}
\begin{markdown}
# markdown

markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown

Right Left Default Center
12 12 12 12
123 123 123 123
1 1 1 1

: table 1 \end{markdown} \end{document}

Some examples are better so that I can understand and learn more.

Thanks for your reading and answer!


Edit

As the answers say, we can copy codes from markdown.sty to our files. However don't put \makeatletter and \makeatother at wrong position. They should be put outside \markdownSetup, just like that:

\makeatletter 
\markdownSetup{
  renderers = {
    table = {%
    \markdownLaTeXTable={}%
    \markdownLaTeXTableAlignment={}%
    \markdownLaTeXTableEnd={%
      \markdownLaTeXBottomRule
      \end{tabular}}%
    \ifx\empty#1\empty\else
      \addto@hook\markdownLaTeXTable{%
        \begin{table}[htbp]
        \centering\caption{#1}\vspace{3pt}}%
      \addto@hook\markdownLaTeXTableEnd{%
        \end{table}}%
    \fi
    \addto@hook\markdownLaTeXTable{\begin{tabular}}%
    \markdownLaTeXRowCounter=0%
    \markdownLaTeXRowTotal=#2%
    \markdownLaTeXColumnTotal=#3%
    \markdownLaTeXRenderTableRow
    }, 
    link = {\href{#3}{#1}},
    image = {\begin{figure}[htb]
      \centering
      \includegraphics[width = .9\linewidth]{#3}%
      \ifx\empty#4\empty\else
        \caption{#4}\label{fig:#1}%
      \fi
    \end{figure}}
  }                                               
}
\makeatother

If you are making templates, you don't need to add the two commands.


2 Answers2

4

You can specify that LaTeX should not make tables float:

\usepackage{float}
\makeatletter
\renewcommand*{\fps@table}{H}
\makeatother

This way, you can avoid the redefinition of the table renderer.

Witiko
  • 1,216
3

To follow the approach described in the question:

\documentclass{article}
\usepackage{markdown}
\markdownSetup{pipeTables = true}                   
\markdownSetup{tableCaptions = true}
\makeatletter
\markdownSetup{renderers={
  table = {%
    \markdownLaTeXTable={}%
    \markdownLaTeXTableAlignment={}%
    \markdownLaTeXTableEnd={%
      \markdownLaTeXBottomRule
      \end{tabular}}%
    \ifx\empty#1\empty\else
      \addto@hook\markdownLaTeXTable{%
        \begin{table}[htbp]
        \centering}%
      \addto@hook\markdownLaTeXTableEnd{%
        \caption{#1}
        \end{table}}%
    \fi
    \addto@hook\markdownLaTeXTable{\begin{tabular}}%
    \markdownLaTeXRowCounter=0%
    \markdownLaTeXRowTotal=#2%
    \markdownLaTeXColumnTotal=#3%
    \markdownLaTeXRenderTableRow
  }
}}
\makeatother
\usepackage{fancyhdr}
\pagestyle{fancy}
\fancyhf{}
\begin{document}
\begin{markdown}
# markdown

markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown markdown

Right Left Default Center
12 12 12 12
123 123 123 123
1 1 1 1

: table 1 \end{markdown} \end{document}

Result:

enter image description here

Marijn
  • 37,699
  • It worked! I know why I failed: I put all these code table = ... into renderers = { ... } as user-manual says. However they should be put into rendererPrototypes={...} as markdown.sty does.

    Now I can control it !

    Cheers!

    – yfzhao20 Aug 08 '21 at 14:46
  • 1
    @yfzhao20: That's likely not why it failed, but it's difficult to check since you didn't provide a working example in your original question. As a user, you should redefine renderers, not renderer prototypes. Renderer prototypes are defined by packages and provide defaults. – Witiko Aug 08 '21 at 15:16
  • 2
    @yfzhao20 indeed the code in my answer also works when using renderers instead of rendererPrototypes. I have edited the answer because renderers seems a cleaner way of doing the definition as Witiko points out. – Marijn Aug 08 '21 at 15:47
  • 1
    The main reason why renderers is shorter than rendererPrototypes: to discourage the use of the latter. – Witiko Aug 08 '21 at 16:27
  • 1
    After rechecking I know what happened: I put \makeatletter and makeatother at wrong position. They should not be put into \markdownSetup{...}. Now I am creating templates and it seems they are needless. – yfzhao20 Aug 08 '21 at 17:13
  • Indeed, you should not need \makeatletter and \makeatother. If you do need them, because you are using a command with @ in its name, then the \makeatletter and \makeatother should go around \markdownSetup{...}, not inside it, so that the commands with @ are correctly tokenized. – Witiko Mar 05 '22 at 19:16