user109114
user109114

Reputation: 403

Internal links in HTML slides made from markdown with pandoc

According to pandoc(1), pandoc supports internal links in HTML slides. But nothing happens for me when I click one.

A minimal example:

% A minimal example
% moi
% 2015-04-04

# Section 1

la la la

# Section 2

cf. [Section 1](#section-1)

I save the foregoing as example.md. Then in bash I run

file=example && \
pandoc -fmarkdown -tslidy --standalone --self-contained -o$file.html $file.md

Having opened the resulting HTML slides in a web browser, I click "Section 1" on slide "Section 2", but nothing happens. This I have tried in multiple browsers on multiple devices: xombrero on a Macbook running Arch Linux, Chrome on a Moto X running Android and Chrome on a Sony laptop running Windows 8.1. The results are the same. I am using pandoc version 1.13.2.

The link produced by pandoc for the internal reference is different from the link of the relevant slide: in the present example, the former ends in #section-1 and, the latter, in #(2). I suppose that this is why clicking the internal link does not return to the relevant slide. Is there some way to achieve that internal links do go to their relevant slides?

Here's the relevant HTML:

<body>
<div class="slide titlepage">
  <h1 class="title">A minimal example</h1>
  <p class="author">
moi
  </p>
  <p class="date">2015-04-04</p>
</div>
<div id="section-1" class="slide section level1">
<h1>Section 1</h1>
<p>la la la</p>
</div>
<div id="section-2" class="slide section level1">
<h1>Section 2</h1>
<p>cf. <a href="#section-1">Section 1</a></p>
</div>
</body>

Thanks for any help!

Upvotes: 1

Views: 867

Answers (2)

sjr
sjr

Reputation: 46

Although the question is stated more than five years ago, I recently had the same problem and created a postprocessing script in Python, which works for me. Essentially it is reading the Pandoc -> Slidy html output, scanning for internal links and replacing them with the slide number on which the link id is defined.

def Fix_Internal_Slidy_Links(infilename, outfilename):
    """Replaces all internal link targets with targets of the respective slidy page number
    """
    page_pattern = ' class=\"slide';
    id_pattern = ' id=\"';
    internal_link_pattern = '<a href=\"#';
    id_dict = dict();
    whole_text = [];
    cur_page = 0;
    #
    # First read all ids and associate them with the current page in id_dict
    with open(infilename, 'r', encoding='utf-8') as filecontent:
        for idx_cur_line, cur_line in enumerate(filecontent):
            whole_text += [cur_line];
            if (page_pattern in cur_line):
                cur_page += 1;
            #
            if (id_pattern in cur_line):
                while (id_pattern in cur_line):
                    startidx = cur_line.index(id_pattern);
                    cur_line = cur_line[startidx+len(id_pattern):];
                    lineparts = cur_line.split('"');
                    # Check if the current id is properly ended
                    if (len(lineparts) > 1):
                        id_dict.update([(lineparts[0], cur_page)]);
    #
    # Then process the code again and replace all internal links known in id_dict
    with open(outfilename, 'w', encoding='utf-8') as filecontent:
        for cur_line in whole_text:
            if (internal_link_pattern in cur_line):
                temp_line = '';
                offset = 0;
                while (internal_link_pattern in cur_line):
                    startidx = cur_line.index(internal_link_pattern);
                    # Extract name
                    temp_line += cur_line[offset:startidx+len(internal_link_pattern)];
                    cur_line = cur_line[startidx+len(internal_link_pattern):];
                    lineparts = cur_line.split('"');
                    if (len(lineparts) < 2):
                        # It seems that the id is not properly finished
                        break;
                    #
                    link = lineparts[0];
                    try:
                        # Create a link to the page assigned to that id
                        replacement_link = '(' + str(id_dict[link]) + ')"';
                    except:
                        # The link reference is not known in id_dict so do not change it
                        replacement_link = lineparts[0] + '"';
                    #
                    temp_line += replacement_link;
                    cur_line = cur_line[len(lineparts[0])+1:];
                #
                cur_line = temp_line + cur_line;
            #
            filecontent.write(cur_line);
#

Upvotes: 0

Tony Williams
Tony Williams

Reputation: 648

Your problem is not with Pandoc but with Slidy. Pandoc is creating the right HTML for an ordinary HTML page but the Slidy slide software does not support going to a <div> - only going to a slide number.

If you change your link to cf. [Section 1](#(2)) ('2' being the number of the slide with 'Section 1') then it will work fine.

BTW - It works perfectly in a reveal.js slideshow created by Pandoc.

Upvotes: 2

Related Questions