From c86fea4089ffa6f22204e8192ce8d73a13e15cc6 Mon Sep 17 00:00:00 2001 From: "Kyle J. McKay" Date: Sun, 20 Oct 2019 23:13:34 -0700 Subject: [PATCH] Markdown: enhance link handling Allow links of the form [...](#...) to find themselves on the page the same way links of the form [...] can. Be flexible accepting either '-' or '_' in place of spaces in the heading name since fragment names may not contain spaces. Refactor the code that manufactures "img" and "a" tags to both simplify the code and make sure that all href, src, alt and title attributes are fully and properly "escaped". In addition, if the "title" for an image ends with something that looks like "(512x342)", "(?x342)" or "(512x?)" then strip that out of the title and set the appropriate width and height attributes on the manufactured "img" tag. For example something like this: ![Nice pic](pic.jpg "Nice (500x300)") or this: ![Nice pic][1] [1]: "Nice (500x300)" now produces this: Nice pic Update the syntax doc to mention these additions. Signed-off-by: Kyle J. McKay --- Markdown.pl | 180 +++++++++++++++++++++++++++------------------------- syntax.md | 34 +++++++++- 2 files changed, 126 insertions(+), 88 deletions(-) diff --git a/Markdown.pl b/Markdown.pl index 2cc28ce..d457813 100755 --- a/Markdown.pl +++ b/Markdown.pl @@ -73,6 +73,7 @@ my %g_perm_block_ids; my %g_urls; my %g_titles; my %g_anchors; +my %g_anchors_id; my %g_block_ids; my %g_html_blocks; my %g_code_blocks; @@ -794,6 +795,22 @@ sub _ProcessWikiLink { } +# Return a suitably encoded tag string +# On input NONE of $url, $text or $title should be xmlencoded +# but $url should already be url-encoded if needed, but NOT g_escape_table'd +sub _MakeATag { + my ($url, $text, $title) = @_; + defined($url) or $url=""; + defined($text) or $text=""; + defined($title) or $title=""; + + my $result = "" . $text . ""; +} + + sub _DoAnchors { # # Turn Markdown link shortcuts into XHTML tags. @@ -845,25 +862,16 @@ sub _DoAnchors { my $result; my $whole_match = $1; my $link_text = $2; - my $link_id = _strip(lc $3); + my $link_id = $3; - if ($link_id eq "") { - $link_id = _strip(lc $link_text); # for shortcut links like [this][]. - } + $link_id ne "" or $link_id = $link_text; # for shortcut links like [this][]. + $link_id = _strip(lc $link_id); if (defined($g_urls{$link_id}) || defined($g_anchors{$link_id})) { my $url = $g_urls{$link_id}; $url = defined($url) ? _PrefixURL($url) : $g_anchors{$link_id}; - # We've got to encode these to avoid conflicting - # with italics, bold and strike through. - $url =~ s!([*_~])!$g_escape_table{$1}!g; - $result = " tag string +# On input NONE of $url, $alt or $title should be xmlencoded +# but $url should already be url-encoded if needed, but NOT g_escape_table'd +sub _MakeIMGTag { + my ($url, $alt, $title) = @_; + defined($url) or $url=""; + defined($alt) or $alt=""; + defined($title) or $title=""; + return "" unless $url ne ""; + + my $result = " tags. @@ -978,25 +1008,15 @@ sub _DoImages { }{ my $result; my $whole_match = $1; - my $alt_text = _strip($2); - my $link_id = _strip(lc $3); + my $alt_text = $2; + my $link_id = $3; - if ($link_id eq "") { - $link_id = lc $alt_text; # for shortcut links like ![this][]. - } + $link_id ne "" or $link_id = $alt_text; # for shortcut links like ![this][]. + $link_id = _strip(lc $link_id); - $alt_text = _EncodeAttText($alt_text); if (defined $g_urls{$link_id}) { - my $url = _PrefixURL($g_urls{$link_id}); - # We've got to encode these to avoid conflicting - # with italics, bold and strike through. - $url =~ s!([*_~])!$g_escape_table{$1}!g; - $result = "\"$alt_text\""; 64; - "_".$link."_"; + $link = "_".$link."_"; + $link =~ s/__+/_/gs; + $link = "_".md5_hex($link)."_" if length($link) > 66; + return $link; } @@ -1116,6 +1119,13 @@ sub _GetNewAnchorId { my $id = _MakeAnchorId($link); return '' unless $id; $g_anchors{$link} = '#'.$id; + $g_anchors_id{$id} = $g_anchors{$link}; + if ($id =~ /-/) { + my $id2 = $id; + $id2 =~ s/-/_/gs; + $id2 =~ s/__+/_/gs; + defined($g_anchors_id{$id2}) or $g_anchors_id{$id2} = $g_anchors{$link}; + } $id; } diff --git a/syntax.md b/syntax.md index c31ef43..d1bdf26 100644 --- a/syntax.md +++ b/syntax.md @@ -876,6 +876,24 @@ already a previous definition with the same id. You can use this to place a table-of-contents at the top of the document that links to subsections later in the document. Just like this document. +For example, all six of these links point to subsections later in +the same document: + + * Self Same + * [Introduction] + * [Part Two] + * [Part Three] + * Different + * [Introduction](#Part-Two) + * [Part Two](#Part_Three) + * [Part Three](#introduction) + + ## Introduction + + ## Part Two + + ## Part Three + Here's an example of reference links in action: I get 10 times more traffic from [Google] [1] than from @@ -1064,9 +1082,19 @@ are defined using syntax identical to link references: [id]: url/to/image "Optional title attribute" -As of this writing, Markdown has no syntax for specifying the -dimensions of an image; if this is important to you, you can simply -use regular HTML `` tags. +To specify one or both dimensions of an image, include the dimensions +in parentheses at the end of the title like so: + + [id]: url/to/image "Optional title attribute (512x342)" + +To resize in just one dimension, specify the other as a "?" like so: + + [id]: url/to/image "Optional title attribute (?x342)" + [id]: url/to/image "Optional title attribute (512x?)" + +The first dimension sets the "width" attribute and the second +dimension sets the "height" attribute. The dimensions are then +removed from the "title" attribute. - - - - -