Ordered list of fenced code blocks doesn't work

I’m trying to make an ordered list of fenced code blocks and text items. I use

/* dec2Hex.c
 * Converts from decimal to hexadecimal

#include <stdio.h>

int main(void)
  unsigned int value;

  printf("Decimal: ");
  scanf("%u", &value);
  printf("%u = 0x%02x\n", value, value);

  return 0;
# coinFlips2.s
# flips a coin, heads/tails
        .intel_syntax noprefix

# Useful constants
        .equ    MIDDLE, 1073741823  # half of RAND_MAX
        .equ    STACK_ALIGN, 8

# Constant data
        .section .rodata
        .string	"heads"
        .string	"tails"

# The code
        .globl  main
        .type   main, @function
        push    rbp         # save frame pointer
        mov     rbp, rsp    # set new frame pointer
        push    r12     # save, use for i
        sub     rsp, STACK_ALIGN
        mov     r12, 0  # i = 0;
        cmp     r12, 10 # any more?
        jae     done    # no, all done
        call    random@plt          # get a random number
        cmp     eax, MIDDLE         # which half?
        jg      tails
        lea     rdi, headsMsg[rip]  # it was heads
        call    puts@plt
        jmp     next    # jump over else block
        lea     rdi, tailsMsg[rip]  # it was tails
        call    puts@plt
next:   inc     r12     # i++;
        jmp     for
        add     rsp, STACK_ALIGN    # realign stack ptr
        pop     r12     # restore for caller
        mov     rsp, rbp    # restore stack pointer
        pop     rbp         # restore frame pointer
  1. The integer is -1, and the string is ffffffff.

This shows correctly in GitHub’s markdown rendering, but the HTML generated starts each of the three items on this list with a 1. Earlier in this same document, the ordered lists work just fine with text and table items. Is there any way to place fenced code blocks on an ordered list?

If you could paste the generated markdown (verbatim) it would be helpful. Once the problem is spotted in the markup, you should be able to easily fix your gen-code accordingly.

Yes. Here’s the markdown (GFM) source:

1. ```c
   printf("Decimal: ");

and here’s how it’s rendered:

  1. printf("Decimal: ");
  1. foo

    int main (void) {
  2. foo

    int main (char*) {

1. foo

    int main (void) {

1. foo

    int main (char*) {

This seems correct markdown code, but results might vary depending on the actual HTML renderer/engine used — the empty line between the two list elements is what might break their numeral sequence in HTML: some renderers require the empty line, others will treat it as an indication of a new list.

GitHub uses its own markdown flavor (GFM), but its HTML rendering rules vary slightly in the context of repository documentation previews and Issues/Discussions, and other thread-based services.

You should consult the Common Mark spec to ensure you’re abiding to it in your generated markdown:


but also need to check the rendering engine used — and, if your markdown code is going to be used across different engines, you might need to adapt it to cover their needs via some options.

Which renderer are you using to generate the final HTML doc?

I’m not the original poster. Just offering something that should work. Although I suppose I should have verified it in github.com instead of github.community.

Well, this is very embarrassing. I was not indenting the items (fenced code) in the list. When I followed the rules, it all worked as it should. Thank you tajmone and jsoref for taking the time to help me, and I apologize for not being more careful before asking. I’m a retired computer science professor, so I suppose this is some sort of karma. Please don’t tell any of my ex-students. :slight_smile:

1 Like

In principle that was correct, since markdown allows “lazy” formatting. The problem is that many non-Common Mark compliant parsers tend to be permissive about lazy formatting, which is positive on the one hand, but it has also been the root cause of discrepancies in behavior across different renderers.

The Common Mark spec was the result of many years of discussions on the problems of markdown inconsistencies, and it was introduced to allow markdown parsers and renderers to move toward a unified syntax.

As you can see, the section on lists is rather long to read. Although the basic rules are few, the Spec covers all edge cases and context that might affect lists. The markdown syntax remain simple to learn and use, but it was tweaked slightly to ensure rules and results consistency across different contexts. Some subtle aspects are rather trick, e.g. like list elements indentation being affected by the width of the list marker — exact indentation size has always been a major cause of cross-renders problems, some parsers expecting 2 spaces, other 3, and others even 4, not to mention tabs being interpreted differently from one library to another.

When I need to work with markdown code generators that need to target different markdown engines, I usually rely on pandoc — i.e. I generated either pandoc’s markdown flavor or a pandoc document AST (JSON), and let pandoc convert it to desired markdown engine.

Pandoc supports multiple markdown flavors, both as input and output formats:

and by tweaking various options and enabling/disabling extensions, you can mimic almost any markdown engine.

So pandoc is definitely the tool to go when generating markup aimed at multiple rendering engines, with the added benefit that if you generate your document as a pandoc AST, you’re not limited to markdown either, but can also target al the other tons of lightweight markup syntaxes covered by pandoc, and many other documents formats.

Thank you very much for your help, Tristano. Your comments helped to inspire me to install pandoc on my Windows machine (where I’m doing much of the writing for my book) and learn a lot more about using it. In particular, I learned from the documentation (when in doubt, read the manual) that I need to convert from gfm, not markdown, to get good results. Wish I would’ve done this long ago. Very helpful!

Glad it helped.

You might also look into PP, a pandoc-preprocessor which extends pandoc by allowing both built-in and custom macros. In this project of mine (a bit old) you’ll find and introduction to PP and some sample macros: