Giter Site home page Giter Site logo

Support for footnotes about discount HOT 8 CLOSED

al3xandru avatar al3xandru commented on September 26, 2024
Support for footnotes

from discount.

Comments (8)

Orc avatar Orc commented on September 26, 2024

I've never really seen the point of that sort of footnote, so I've not spent any significant time thinking about how to implement it.

But I don't think it would be difficult to implement. After I've shaken any bugs out of 2.0.4 and have it actually released I'll see how quickly I could hack out an implementation.

from discount.

al3xandru avatar al3xandru commented on September 26, 2024

Unfortunately my C brain cells have been washed away so I cannot really provide a patch for this feature.

Anyways considering reference links support, footnote support should not be too complicated. Actually I think discount is already "retrieving" footnotes, but spits them out in the wrong format.

What I mean by that is that given the format I've mentioned, discount will actually generate in the place of the footnote ref (inline) a link containing the text of the footnote. While basically tells me that adding a footnote ref format matcher in the link function ("does the link text start with ^?") would partially address the reference part.

Then at the end of processing discount would just need to check if there are any unused "links" those becoming the footnotes. But this may be an oversimplified perspective.

from discount.

Orc avatar Orc commented on September 26, 2024

There are more details than that.

  1. markdown extra style footnotes actually have a different format -- [^id]: text instead of [id]: uri text,
  2. footnotes are ordered numerically (1..n) despite what the [^id] is, and as a result of that
  3. they've got to be printed out in that order, not just dumped out in the order that they were added to (or sorted into) the footnote list.
  4. which means that the list only consists of referenced footnotes.

This means some data structure changes (need to add a referenced flag to each footnote, as well as a footnote #; possibly need to add a per-document next-footnote-number which is updated when the document is parsed) and code changes (the footnote slurper needs to be able to deal with both formats of footnote, the [] handler needs to be able to deal with [^] footnotes, and a footnote dumper needs to be written to dump the list out in as-referenced order.

I threw together a simple test patch for it this morning (w/o proper footnote numbering) and even if it's not unspeakably grotty it's still a fairly ugly thing:

diff --git a/basename.c b/basename.c
diff --git a/docheader.c b/docheader.c
diff --git a/generate.c b/generate.c
index f39dcc9..e637435 100644
--- a/generate.c
+++ b/generate.c
@@ -564,6 +564,35 @@ printlinkyref(MMIOT *f, linkytype *tag, char *link, int size)
 } /* printlinkyref */


+/* php markdown extra/daring fireball style print footnotes
+ */
+static int
+extra_linky(MMIOT *f, Cstring text, Footnote *ref)
+{
+    int size = S(text)-1;
+    char *id = T(text)+1;
+
+    if ( f->flags & IS_LABEL ) {
+           ___mkd_reparse(T(text), S(text), linkt.flags, f);
+   return 1;
+    }
+
+    if ( ref->flags & REFERENCED ) {
+   Qprintf(f, "<sup>");
+   ___mkd_reparse(id, size, linkt.flags, f);
+   Qprintf(f, "</sup>");
+    }
+    else {
+   ref->flags |= REFERENCED;
+   Qprintf(f, "<sup id=\"fnref:%.*s\"><a href=\"#fn:%.*s\" rel=\"footnote\">",
+           size, id, size, id);
+   ___mkd_reparse(id, size, linkt.flags, f);
+   Qprintf(f, "</a></sup>");
+    }
+    return 1;
+} /* extra_linky */
+
+
 /* print out a linky (or fail if it's Not Allowed)
  */
 static int
@@ -628,6 +657,7 @@ linkylinky(int image, MMIOT *f)
     Footnote key, *ref;

     int status = 0;
+    int extra_footnote = 0;

     CREATE(name);
     memset(&key, 0, sizeof key);
@@ -654,6 +684,9 @@ linkylinky(int image, MMIOT *f)
                 */
                mmiotseek(f, implicit_mark);
                goodlink = !(f->flags & MKD_1_COMPAT);
+
+           if ( (!image) && S(name) && T(name)[0] == '^' )
+               extra_footnote = 1;
            }

            if ( goodlink ) {
@@ -664,8 +697,12 @@ linkylinky(int image, MMIOT *f)
                }

                if ( ref = bsearch(&key, T(*f->footnotes), S(*f->footnotes),
-                                     sizeof key, (stfu)__mkd_footsort) )
-               status = linkyformat(f, name, image, ref);
+                                     sizeof key, (stfu)__mkd_footsort) ) {
+               if ( extra_footnote )
+                   status = extra_linky(f,name,ref);
+               else
+                   status = linkyformat(f, name, image, ref);
+           }
                else if ( f->flags & IS_LABEL )
                    status = linkyformat(f, name, image, &imaget);
            }
@@ -1616,6 +1653,40 @@ display(Paragraph *p, MMIOT *f)
 }


+/* dump out a list of footnotes
+ */
+static void
+mkd_extra_footnotes(MMIOT *m)
+{
+    int i, prefix=0;
+    Footnote *t;
+    char *id;
+    int size;
+
+    if ( m->footnotes == 0 )
+   return;
+
+    for ( i=0; i < S(*m->footnotes); i++ ) {
+   t = &T(*m->footnotes)[i];
+   if ( t->flags & REFERENCED ) {
+       if ( !prefix ) {
+           Csprintf(&m->out, "<div class=\"footnotes\">\n<hr/>\n<ol>\n");
+           prefix=1;
+       }
+       id = T(t->tag)+1;
+       size= S(t->tag)-1;
+       Csprintf(&m->out, "<li id=\"%.*s\">\n<p>", size, id);
+       Csreparse(&m->out, T(t->title), S(t->title), 0);
+       Csprintf(&m->out, "<a href=\"#fnref:%.*s\" rev=\"footnote\">&#8617;</a>",
+                   size, id);
+       Csprintf(&m->out, "</p></li>");
+   }
+    }
+    if ( prefix )
+   Csprintf(&m->out, "</ol>\n</div>\n");
+}
+
+
 /* return a pointer to the compiled markdown
  * document.
  */
@@ -1627,6 +1698,7 @@ mkd_document(Document *p, char **res)
     if ( p && p->compiled ) {
        if ( ! p->html ) {
            htmlify(p->code, 0, 0, p->ctx);
+       mkd_extra_footnotes(p->ctx);
            p->html = 1;
        }

diff --git a/markdown.c b/markdown.c
index b239265..78e5cfe 100644
--- a/markdown.c
+++ b/markdown.c
@@ -962,6 +962,12 @@ addfootnote(Line *p, MMIOT* f)
     S(foot->tag)--;
     j = nextnonblank(p, j+2);

+    if ( T(foot->tag)[0] == '^' ) {
+   while ( j < S(p->text) )
+       EXPAND(foot->title) = T(p->text)[j++];
+   goto skip_to_end;
+    }
+
     while ( (j < S(p->text)) && !isspace(T(p->text)[j]) )
        EXPAND(foot->link) = T(p->text)[j++];
     EXPAND(foot->link) = 0;
@@ -1001,6 +1007,7 @@ addfootnote(Line *p, MMIOT* f)
        --S(foot->title);
     }

+skip_to_end:
     ___mkd_freeLine(p);
     return np;
 }
diff --git a/markdown.h b/markdown.h
index 5a6d705..2f2a1d7 100644
--- a/markdown.h
+++ b/markdown.h
@@ -12,6 +12,9 @@ typedef struct footnote {
     Cstring title;         /* what it's called (TITLE= attribute) */
     int height, width;             /* dimensions (for image link) */
     int dealloc;           /* deallocation needed? */
+    int flags;
+#define EXTRA_BOOKMARK     0x01
+#define REFERENCED 0x02
 } Footnote;

 /* each input line is read into a Line, which contains the line,

And I don't really want to add a whole bunch of new code to the baseline yet (it still needs to have the footnotes numbered numerically, and it still needs to have a option flag to turn m-e footnotes on and off, and...) so I'm not going to consider it until after I get 2.0.4 stable enough to strip the beta tag off from.

from discount.

al3xandru avatar al3xandru commented on September 26, 2024

Actually I don't think 2/ + 3/ apply. The behavior is similar to numerical/ordered lists: whatever number you are using, the output will ignore that and just use the document order.

That simplifies a lot of things as you can maintain the "parsing" order and just have a counter for generating output.

I do understand if you don't have the time/or just don't want to add this before the next version is released.

from discount.

Orc avatar Orc commented on September 26, 2024

But cosmetically you need to have the footnote numbers match; If I have

 text here[^zed] and there[^goo]
 [^zed]: is the first footnote.
 [^goo]: is the second footnote

but the footnotes have been sorted so that ^goo comes before ^zed, the labels associated with "here" and "there" won't be like the list items down in the table of footnotes.

from discount.

al3xandru avatar al3xandru commented on September 26, 2024

You are absolutely right :-). While I've never made this mistake, I do agree that the general case should consider this situation.

from discount.

al3xandru avatar al3xandru commented on September 26, 2024

This being closed now, I assume that you decided not to support it, right? I've been able to apply the patch provided in this thread (with small modifications), but I'm not really sure I'll be able to maintain it myself.

from discount.

Orc avatar Orc commented on September 26, 2024

Take a look at the footnotes branch of the discount branch fork. I've not decided whether to put it into the baseline or not (and haven't had the time; discount doesn't even start to pay the bills, so I have to juggle it with the dozen or so other projects I do in my spare time) but a couple of weeks without a significant (and ugly) change going in doesn't mean anything.

Sorry, you'll just have to be patient :-(

from discount.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.