fix even more broken markdown links

Added `bin/find-missing-links.sh` tool to check for
markdown links to missing local files.

Regarding the missing link tool:

```
    Here be extended regular expression magic dragons! :-)
```

Added `make find_missing_links` to the top level Makefile.

Added `make find_missing_links` to `make www` and `make quick_www`.

Ran `make www` to perform the above.

TODO: Fix markdown links to missing local files.
This commit is contained in:
Landon Curt Noll committed 2024-04-28 01:08:21 -07:00
1 parent 58d19725b4
commit 217836e33f
41 files changed
+1773 -635

No files matched your search

+5 -5
View File
@@ -157,7 +157,7 @@ tackle this project.
on smaller machines; `m[]` needs to be at least 2000 long, though.
I say `first` is portable mainly because it uses native types. Unlike
[FORTH](https://en.wikipedia.org/wiki/Forth_(programming_language), which
[FORTH](https://en.wikipedia.org/wiki/Forth_(programming_language)), which
traditionally allows byte and multi-byte operations, all operations are
performed on C `int`s. That means `first` code is only as portable as the same
code would be in C. As in C, the result of dividing `-1` by `2` is machine (or
@@ -205,7 +205,7 @@ represents a step backwards, in more ways than one.)
### What exactly is `first`, then?
`first` is a tiny interpreter which implements a sufficient pseudo-subset of
[FORTH](https://en.wikipedia.org/wiki/Forth_(programming_language)) to allow it
[FORTH](https://en.wikipedia.org/wiki/Forth_(programming_language)) to allow it
to bootstrap a relatively complete version of FORTH (based loosely on forth79),
which I call THIRD. Complete relative to what, I'm not sure.
@@ -217,11 +217,11 @@ the design file, design, I give a justification for why each primitive in
THIRD is sorta slow, because `first` has so few primitives that many things that
are primitives in
[FORTH](https://en.wikipedia.org/wiki/Forth_(programming_language)) (like swap)
[FORTH](https://en.wikipedia.org/wiki/Forth_(programming_language)) (like swap)
take a significant amount of time in THIRD.
When you get the `Ok.` message from `third`, try out some sample
[FORTH](https://en.wikipedia.org/wiki/Forth_(programming_language)) code
[FORTH](https://en.wikipedia.org/wiki/Forth_(programming_language)) code
(`first` has no way of knowing if keyboard input is waiting, so it can't actually prompt
you in a normal way. It only prints `'Ok.'` after you define a word).
@@ -266,7 +266,7 @@ If you compile the basic THIRD system without the help word (strings take up one
1000 `int`s (plus the return stack).
Thus THIRD gives you a relatively complete
[FORTH](https://en.wikipedia.org/wiki/Forth_(programming_language)) system in
[FORTH](https://en.wikipedia.org/wiki/Forth_(programming_language)) system in
less than 700 chars of C source + about 1000 `int`s of memory--and it's portable
too (you could copy over the THIRD memory dump to another machine, in theory).
If the above numbers seem to you to be mixing apples and oranges (C source and
+1 -1
View File
@@ -484,7 +484,7 @@ tackle this project.</p>
<p><code>first</code> is reasonably portable. You may need to adjust the size of the buffers
on smaller machines; <code>m[]</code> needs to be at least 2000 long, though.</p>
<p>I say <code>first</code> is portable mainly because it uses native types. Unlike
[FORTH](https://en.wikipedia.org/wiki/Forth_(programming_language), which
<a href="https://en.wikipedia.org/wiki/Forth_(programming_language)">FORTH</a>, which
traditionally allows byte and multi-byte operations, all operations are
performed on C <code>int</code>s. That means <code>first</code> code is only as portable as the same
code would be in C. As in C, the result of dividing <code>-1</code> by <code>2</code> is machine (or
+1 -1
View File
@@ -37,7 +37,7 @@ International Internet community.
## Author's remarks:
This program plays
[Mastermind](https://en.wikipedia.org/wiki/Mastermind_(board_game), if you call
[Mastermind](https://en.wikipedia.org/wiki/Mastermind_&#x28;board_game&#x29;), if you call
it by a name ending by 'd', otherwise it _solves_ Mastermind. Call it without
parameters to use 6 digits (colors), or indicate the number of possible digits
(you cannot change the number of positions so easily).
+1 -1
View File
@@ -414,7 +414,7 @@ for instructions of how to play.</p>
International Internet community.</p>
<h2 id="authors-remarks">Author’s remarks:</h2>
<p>This program plays
[Mastermind](https://en.wikipedia.org/wiki/Mastermind_(board_game), if you call
<a href="https://en.wikipedia.org/wiki/Mastermind_(board_game)">Mastermind</a>, if you call
it by a name ending by ‘d’, otherwise it <em>solves</em> Mastermind. Call it without
parameters to use 6 digits (colors), or indicate the number of possible digits
(you cannot change the number of positions so easily).</p>
+1 -1
View File
@@ -74,7 +74,7 @@ Use `rince.alt` or `rince.alt2` as you would `rince` above.
The author has provided several CABBAGE files for your amusement:
- [rince.data1](%%REPO_URL%%/1993/rince/rince.data1) plays
[Breakout](https://en.wikipedia.org/wiki/Breakout_(video_game). Keys are `,`
[Breakout](https://en.wikipedia.org/wiki/Breakout_&#x28;video_game&#x29;). Keys are `,`
for left, `/` for right, and `.` for 'fire the ball'.
- [rince.data2](%%REPO_URL%%/1993/rince/rince.data2) plays the old [James Bonfield](../../authors.html#James_Bonfield)'s
+1 -1
View File
@@ -430,7 +430,7 @@ changed).</p>
<p>The author has provided several CABBAGE files for your amusement:</p>
<ul>
<li><p><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/1993/rince/rince.data1">rince.data1</a> plays
[Breakout](https://en.wikipedia.org/wiki/Breakout_(video_game). Keys are <code>,</code>
<a href="https://en.wikipedia.org/wiki/Breakout_(video_game)">Breakout</a>. Keys are <code>,</code>
for left, <code>/</code> for right, and <code>.</code> for ‘fire the ball’.</p></li>
<li><p><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/1993/rince/rince.data2">rince.data2</a> plays the old <a href="../../authors.html#James_Bonfield">James Bonfield</a>’s
(<a href="../../1991/rince/index.html">1991/rince</a> game from IOCCC 1991.</p></li>
+1 -1
View File
@@ -39,7 +39,7 @@ them for the next IOCCC.
We believe you will be impressed with this year's winning entries The [Best of
Show](ollinger/index.html) is a fine example of obfuscation. But don't ignore
the other entries! There are games, programs that speak, ones that compile code
and [one that _might_ run binaries you already have](2001/anonymous/index.html).
and [one that _might_ run binaries you already have](anonymous/index.html).
The [Best/Worst Abuse of the Rules](bellard/index.html) is technically allowed by the
[rules](rules.txt). This year we awarded it again, but don't assume you can get
+1 -1
View File
@@ -412,7 +412,7 @@ them for the next IOCCC.</p>
<p>We believe you will be impressed with this year’s winning entries The <a href="ollinger/index.html">Best of
Show</a> is a fine example of obfuscation. But don’t ignore
the other entries! There are games, programs that speak, ones that compile code
and <a href="2001/anonymous/index.html">one that <em>might</em> run binaries you already have</a>.</p>
and <a href="anonymous/index.html">one that <em>might</em> run binaries you already have</a>.</p>
<p>The <a href="bellard/index.html">Best/Worst Abuse of the Rules</a> is technically allowed by the
<a href="rules.txt">rules</a>. This year we awarded it again, but don’t assume you can get
away with using the same technique next time … :-)</p>
+1 -1
View File
@@ -48,7 +48,7 @@ aren't familiar with it. Back in its day, this demo inspired lust and awe in
geeks around the world.
The graphics are
[raytraced](https://en.wikipedia.org/wiki/Ray_tracing_(graphics), with
[raytraced](https://en.wikipedia.org/wiki/Ray_tracing_&#x28;graphics&#x29;), with
procedural textures on the ball and the back wall. I did cheat a little to
simplify the calculations: it uses a parallel projection, but textures the back
wall to look as if there were a floor being viewed in perspective. The shadow
+1 -1
View File
@@ -421,7 +421,7 @@ the Commodore Amiga. See <a href="https://www.youtube.com/watch?v=-ga41edXw3A" c
aren’t familiar with it. Back in its day, this demo inspired lust and awe in
geeks around the world.</p>
<p>The graphics are
[raytraced](https://en.wikipedia.org/wiki/Ray_tracing_(graphics), with
<a href="https://en.wikipedia.org/wiki/Ray_tracing_(graphics)">raytraced</a>, with
procedural textures on the ball and the back wall. I did cheat a little to
simplify the calculations: it uses a parallel projection, but textures the back
wall to look as if there were a floor being viewed in perspective. The shadow
+1 -1
View File
@@ -292,7 +292,7 @@ casting) it to an integer-type variable.
[pour-out.txt](%%REPO_URL%%/2012/endoh1/pour-out.txt) pours you a cup of tea.
[tanada.txt](%%REPO_URL%%/2012/endoh1/tanada.txt) simulates "Terrace farming". ("Tanada" means a
"[terraced rice](https://en.wikipedia.org/wiki/Terrace_(earthworks) fields)" in Japanese.)
"[terraced rice](https://en.wikipedia.org/wiki/Terrace_&#x28;earthworks&#x29; fields)" in Japanese.)
[clock.txt](%%REPO_URL%%/2012/endoh1/clock.txt) is a "water" clock created by HAMANO Tsukasa.
+1 -1
View File
@@ -132,7 +132,7 @@ As an extra tweak, the text message actually does something useful. Remove the
[^1]: [Russ Cox, Regular Expression Matching: the Virtual Machine Approach](http://swtch.com/~rsc/regexp/regexp2.html)
[^2]: [Regular Expression Matching Can Be Simple And Fast (but is slow in Java, Perl, PHP, Python, Ruby, ...](http://swtch.com/~rsc/regexp/regexp1.html)
[^2]: [Regular Expression Matching Can Be Simple And Fast &#x28;but is slow in Java, Perl, PHP, Python, Ruby, ...&#x29;](http://swtch.com/~rsc/regexp/regexp1.html)
<!--
+1 -1
View File
@@ -460,7 +460,7 @@ amount of spaghetti branches and virtual thread creations. Finally, the VM in
“Make a contract with me” catch line and the program would cease to function.</p>
<h3 id="references">References</h3>
<p>[1] <a href="http://swtch.com/~rsc/regexp/regexp2.html">Russ Cox, Regular Expression Matching: the Virtual Machine Approach</a></p>
<p>[2] <a href="http://swtch.com/~rsc/regexp/regexp1.html">Regular Expression Matching Can Be Simple And Fast (but is slow in Java, Perl, PHP, Python, Ruby, …</a></p>
<p>[2] <a href="http://swtch.com/~rsc/regexp/regexp1.html">Regular Expression Matching Can Be Simple And Fast (but is slow in Java, Perl, PHP, Python, Ruby, …)</a></p>
<hr style="width:10%;text-align:left;margin-left:0">
<p>Jump to: <a href="#">top</a></p>
<!--
+1 -1
View File
@@ -129,7 +129,7 @@ As an extra tweak, the text message actually does something useful. Remove the
[1] [Russ Cox, Regular Expression Matching: the Virtual Machine Approach](http://swtch.com/~rsc/regexp/regexp2.html)
[2] [Regular Expression Matching Can Be Simple And Fast (but is slow in Java, Perl, PHP, Python, Ruby, ...](http://swtch.com/~rsc/regexp/regexp1.html)
[2] [Regular Expression Matching Can Be Simple And Fast &#x28;but is slow in Java, Perl, PHP, Python, Ruby, ...&#x29;](http://swtch.com/~rsc/regexp/regexp1.html)
<hr style="width:10%;text-align:left;margin-left:0">
+1 -1
View File
@@ -492,7 +492,7 @@ amount of spaghetti branches and virtual thread creations. Finally, the VM in
<section id="footnotes" class="footnotes footnotes-end-of-document" role="doc-endnotes">
<h5>Footnotes</h5>
<ol>
<li id="fn1"><p><a href="http://swtch.com/~rsc/regexp/regexp1.html">Regular Expression Matching Can Be Simple And Fast (but is slow in Java, Perl, PHP, Python, Ruby, …</a><a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn1"><p><a href="http://swtch.com/~rsc/regexp/regexp1.html">Regular Expression Matching Can Be Simple And Fast (but is slow in Java, Perl, PHP, Python, Ruby, …)</a><a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2"><p><a href="http://swtch.com/~rsc/regexp/regexp2.html">Russ Cox, Regular Expression Matching: the Virtual Machine Approach</a><a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn3"><p><a href="http://swtch.com/~rsc/regexp/regexp2.html">Russ Cox, Regular Expression Matching: the Virtual Machine Approach</a><a href="#fnref3" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
+1 -1
View File
@@ -180,7 +180,7 @@ for [Khan](https://memory-alpha.fandom.com/wiki/Khan_Noonien_Singh) (in the
final engagement in [Star Trek II: The Wrath of
Khan](https://memory-alpha.fandom.com/wiki/Star_Trek_II:_The_Wrath_of_Khan), the
damaged Enterprise managed to disable the USS
[Reliant](https://memory-alpha.fandom.com/wiki/USS_Reliant_(NCC-1864) ship)'s shield
[Reliant](https://memory-alpha.fandom.com/wiki/USS_Reliant_&#x28;NCC-1864&#x29; ship)'s shield
generator by accessing its prefix code: 16309).
+1 -1
View File
@@ -63,7 +63,7 @@ Who will be the first to tweet this source? How many re-tweets will such tweet
get? And how many people will really understand the tweet?
Judges' 2023 update: Last year we would have referred to a
[toot](https://en.wikipedia.org/wiki/Mastodon_\(social_network\)#Comparison_to_Twitter),
[toot](https://en.wikipedia.org/wiki/Mastodon_&#x28;social_network&#x29;#Comparison_to_Twitter),
as in a [Mastodon](https://fosstodon.org/@ioccc) *toot*.
This year we might have mentioned the term
[publish](https://www.itechpost.com/articles/115087/20221116/mastodon-officially-replaced-toot-publish.htm)
+2 -2
View File
@@ -49,8 +49,8 @@ It is something completely different.
The [Most likely to be awarded - 2018/ciura](ciura/index.html) has an amazing vocabulary!
There are also nods to entries of the years [2000/bellard](2000/bellard/index.html),
[1989/yang](1989/yang/index.html), ...
There are also nods to entries of the years [2000/bellard](../2000/bellard/index.html),
[1989/yang](../1989/yang/index.html), ...
...We'll stop spouting spoilers now. Have fun exploring all the entries!
+1 -1
View File
@@ -38,7 +38,7 @@ sketch [comté](https://en.wikipedia.org/wiki/Comté_cheese) called ["Dead
Parrot"](https://en.wikipedia.org/wiki/Dead_Parrot_sketch) from the British
sitcom ["Monty Python's Flying Circus"](https://en.wikipedia.org/wiki/Monty_Python%27s_Flying_Circus)
The "_Python_" in the award name refers to Monty Python, **not** the
[programming language Python](https://en.wikipedia.org/wiki/Python_(programming_language)
[programming language Python](https://en.wikipedia.org/wiki/Python_&#x28;programming_language&#x29;
(the name of the programming language Python is derived from Monty Python).
The shape of [prog.c](%%REPO_URL%%/2018/endoh2/prog.c) is "Undead Parrot" based on "dead parrot". The
+2 -2
View File
@@ -415,8 +415,8 @@ of the <a href="poikola/index.html">Most stellar - 2018/poikola</a>.</p>
<p>The <a href="endoh2/index.html">Best use of python - 2018/endoh2</a> is a not what you might think it is.
It is something completely different.</p>
<p>The <a href="ciura/index.html">Most likely to be awarded - 2018/ciura</a> has an amazing vocabulary!</p>
<p>There are also nods to entries of the years <a href="2000/bellard/index.html">2000/bellard</a>,
<a href="1989/yang/index.html">1989/yang</a>, …</p>
<p>There are also nods to entries of the years <a href="../2000/bellard/index.html">2000/bellard</a>,
<a href="../1989/yang/index.html">1989/yang</a>, …</p>
<p>…We’ll stop spouting spoilers now. Have fun exploring all the entries!</p>
<h2 id="remarks-on-some-of-submissions-that-did-not-win">Remarks on some of submissions that did not win</h2>
<p>The number of entries that would have made it into the final rounds
+1 -1
View File
@@ -45,7 +45,7 @@ These nods to not run afoul of the guideline:
are rather similar to previous entries
```
because the entry [2019/dogon](2019/dogon/index.html) appropriately pays homage
because the entry [2019/dogon](dogon/index.html) appropriately pays homage
to past entries without blatantly reusing their code.
...We'll stop spouting spoilers now. Have fun exploring all the entries!
+1 -1
View File
@@ -412,7 +412,7 @@ vocabulary!</p>
<pre><code> We tend to dislike programs that:
...
are rather similar to previous entries</code></pre>
<p>because the entry <a href="2019/dogon/index.html">2019/dogon</a> appropriately pays homage
<p>because the entry <a href="dogon/index.html">2019/dogon</a> appropriately pays homage
to past entries without blatantly reusing their code.</p>
<p>…We’ll stop spouting spoilers now. Have fun exploring all the entries!</p>
<h2 id="remarks-on-some-of-submissions-that-did-not-win">Remarks on some of submissions that did not win</h2>
+1 -1
View File
@@ -33,7 +33,7 @@ For some reason, this year's set of winning entries contains three nostalgic gam
and [Snake - 2020/ferguson1](ferguson1/index.html).
An entry, [kurdyukov1](kurdyukov1/index.html), pays homage to previous entry
[2015/hou](2015/hou/index.html).
[2015/hou](../2015/hou/index.html).
...We'll stop spouting spoilers now. Have fun exploring all the entries!
+1 -1
View File
@@ -405,7 +405,7 @@ IOCCC list!</p>
<a href="tsoj/index.html">Asteroids - 2020/tsoj</a>, <a href="endoh1/index.html">Minesweeper - 2020/endoh1</a>,
and <a href="ferguson1/index.html">Snake - 2020/ferguson1</a>.</p>
<p>An entry, <a href="kurdyukov1/index.html">kurdyukov1</a>, pays homage to previous entry
<a href="2015/hou/index.html">2015/hou</a>.</p>
<a href="../2015/hou/index.html">2015/hou</a>.</p>
<p>…We’ll stop spouting spoilers now. Have fun exploring all the entries!</p>
<h2 id="remarks-on-some-of-submissions-that-did-not-win">Remarks on some of submissions that did not win</h2>
<p>As a rule, we try to compile the entries on a variety of platforms. Quite a few
+13 -1
View File
@@ -65,6 +65,7 @@ TAR_YEAR= bin/tar-year.sh
GEN_STATUS= bin/gen-status.sh
GEN_SITEMAP= bin/gen-sitemap.sh
SORT_GITIGNORE= bin/sort.gitignore.sh
FIND_MISSING_LINKS= bin/find-missing-links.sh
#############
@@ -241,7 +242,7 @@ indent.c:
# simple want to examine, run / test winning IOCCC entries.
.PHONY: help genpath genfilelist verify_entry_files gen_authors gen_location gen_years \
entry_index gen_top_html thanks gen_other_html quick_entry_index \
find_missing_links entry_index gen_top_html thanks gen_other_html quick_entry_index \
gen_year_index quick_www www \
untar_entry_tarball untar_year_tarball \
form_entry_tarball form_year_tarball tar \
@@ -271,6 +272,7 @@ help:
@echo "make gen_top_html - generate a number of the top level HTML files from markdown"
@echo "make gen_status - generate status.json and status.html"
@echo "make quick_entry_index - build winner index.html files that might be out of date"
@echo "make find_missing_links - find markdown links to missing local files"
@echo "make quick_www - generate html files more quickly, checking timestamps"
@echo "make www - build html pages for web site"
@echo
@@ -335,6 +337,7 @@ genfilelist:
verify_entry_files: ${ALL_RUN} ${CHK_ENTRY}
@echo '=-=-=-=-= IOCCC begin make $@ =-=-=-=-='
${ALL_RUN} -v 3 ${CHK_ENTRY}
@echo '=-=-=-=-= IOCCC complete make $@ =-=-=-=-='
# sort .gitignore files according to rules in bin/sgi.sh
#
@@ -433,6 +436,13 @@ quick_entry_index quick_readme2index: ${ALL_RUN} ${QUICK_README2INDEX}
${ALL_RUN} -v 3 ${QUICK_README2INDEX} -v 1
@echo '=-=-=-=-= IOCCC complete make $@ =-=-=-=-='
# find markdown links to missing local files
#
find_missing_links:
@echo '=-=-=-=-= IOCCC begin make $@ =-=-=-=-='
${FIND_MISSING_LINKS} -v 1
@echo '=-=-=-=-= IOCCC complete make $@ =-=-=-=-='
# do work to build HTML content for the web site
#
# This rule uses quick_entry_index, not slow_entry_index, so
@@ -456,6 +466,7 @@ quick_www:
${MAKE} gen_top_html
${MAKE} gen_status
${MAKE} quick_entry_index
${MAKE} find_missing_links
@echo '=-=-=-=-= IOCCC complete make $@ =-=-=-=-='
# do everything needed to build HTML content for the web site
@@ -477,6 +488,7 @@ www:
${MAKE} gen_top_html
${MAKE} gen_status
${MAKE} entry_index
${MAKE} find_missing_links
@echo '=-=-=-=-= IOCCC complete make $@ =-=-=-=-='
# untar all entry tarballs
+31
View File
@@ -75,6 +75,37 @@ For example:
```
### [find-missing-links.sh](%%DOCROOT_SLASH%%bin/find-missing-links.sh)
Find all markdown links to local files that do not exist.
This tool does **NOT** check of a remote URL exists.
This tool only checks on links to local files.
This tool does **NOT** check links into a given place in a file.
This tool only checks that local files linked by markdown exist.
This tool does **NOT** check HTML file links.
This tool only checks markdown based links.
Usage:
``` <!---sh-->
bin/find-missing-links.sh -v 1
```
If no missing links are found, this tool exits 0 with no output
(debug messages not withstanding), otherwise this tool will exit non-zero.
NOTE: If the markdown link is malformed, this tool
might generate an error about a file that does exist.
If this tool claims that a file is missing that does exist,
look for a malformed markdown line and/or use of markdown
that is **NOT** an IOCCC markdown best practice.
See [IOCCC markdown best practices](markdown.html) for more info.
### [gen-authors.sh](%%DOCROOT_SLASH%%bin/gen-authors.sh)
Generate the top level `/authors.html` page.
+532
View File
@@ -0,0 +1,532 @@
#!/usr/bin/env bash
#
# find-missing-links.sh - find markdown links to missing local files
#
# Find all markdown links to local files that do not exist.
#
# This tool does **NOT** check of a remote URL exists.
# This tool only checks on links to local files.
#
# This tool does **NOT** check links into a given place in a file.
# This tool only checks that local files linked by markdown exist.
#
# This tool does **NOT** check HTML file links.
# This tool only checks markdown based links.
#
# NOTE: If the markdown link is malformed, this tool
# might generate an error about a file that does exist.
# If this tool claims that a file is missing that does exist,
# look for a malformed markdown line and/or use of markdown
# that is **NOT** an IOCCC markdown best practice.
#
# See the IOCCC markdown best practices file, markdown.html, for more info.
#
# Copyright (c) 2024 by Landon Curt Noll. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and
# its documentation for any purpose and without fee is hereby granted,
# provided that the above copyright, this permission notice and text
# this comment, and the disclaimer below appear in all of the following:
#
# supporting documentation
# source copies
# source works derived from this source
# binaries derived from this source or from derived source
#
# LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
# EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
# USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
#
# chongo (Landon Curt Noll, http://www.isthe.com/chongo/index.html) /\oo/\
#
# Share and enjoy! :-)
# firewall - run only with a bash that is version 5.1.8 or later
#
# The "/usr/bin/env bash" command must result in using a bash that
# is version 5.1.8 or later.
#
# We could relax this version and insist on version 4.2 or later. Versions
# of bash between 4.2 and 5.1.7 might work. However, to be safe, we will require
# bash version 5.1.8 or later.
#
# WHY 5.1.8 and not 4.2? This safely is done because macOS Homebrew bash we
# often use is "version 5.2.26(1)-release" or later, and the RHEL Linux bash we
# use often use is "version 5.1.8(1)-release" or later. These versions are what
# we initially tested. We recommend you either upgrade bash or install a newer
# version of bash and adjust your $PATH so that "/usr/bin/env bash" finds a bash
# that is version 5.1.8 or later.
#
# NOTE: The macOS shipped, as of 2024 March 15, a version of bash is something like
# bash "version 3.2.57(1)-release". That macOS shipped version of bash
# will NOT work. For users of macOS we recommend you install Homebrew,
# (see https://brew.sh), and then run "brew install bash" which will
# typically install it into /opt/homebrew/bin/bash, and then arrange your $PATH
# so that "/usr/bin/env bash" finds "/opt/homebrew/bin" (or whatever the
# Homebrew bash is).
#
# NOTE: And while MacPorts might work, we noticed a number of subtle differences
# with some of their ported tools to suggest you might be better off
# with installing Homebrew (see https://brew.sh). No disrespect is intended
# to the MacPorts team as they do a commendable job. Nevertheless we ran
# into enough differences with MacPorts environments to suggest you
# might find a better experience with this tool under Homebrew instead.
#
if [[ -z ${BASH_VERSINFO[0]} ||
${BASH_VERSINFO[0]} -lt 5 ||
${BASH_VERSINFO[0]} -eq 5 && ${BASH_VERSINFO[1]} -lt 1 ||
${BASH_VERSINFO[0]} -eq 5 && ${BASH_VERSINFO[1]} -eq 1 && ${BASH_VERSINFO[2]} -lt 8 ]]; then
echo "$0: ERROR: bash version needs to be >= 5.1.8: $BASH_VERSION" 1>&2
echo "$0: Warning: bash version >= 4.2 might work but 5.1.8 was the minimum we tested" 1>&2
echo "$0: Notice: For macOS users: install Homebrew (see https://brew.sh), then run" \
""brew install bash" and then modify your \$PATH so that \"#!/usr/bin/env bash\"" \
"finds the Homebrew installed (usually /opt/homebrew/bin/bash) version of bash" 1>&2
exit 4
fi
# setup bash file matching
#
# We must declare arrays with -ag or -Ag, and we need loops to "export" modified variables.
# This requires a bash with a version 4.2 or later. See the larger comment above about bash versions.
#
shopt -s nullglob # enable expanded to nothing rather than remaining unexpanded
shopt -u failglob # disable error message if no matches are found
shopt -u dotglob # disable matching files starting with .
shopt -u nocaseglob # disable strict case matching
shopt -u extglob # enable extended globbing patterns
shopt -s globstar # enable ** to match all files and zero or more directories and subdirectories
# set variables referenced in the usage message
#
export VERSION="1.0 2024-04-28"
NAME=$(basename "$0")
export NAME
export V_FLAG=0
GIT_TOOL=$(type -P git)
export GIT_TOOL
if [[ -z "$GIT_TOOL" ]]; then
echo "$0: FATAL: git tool is not installed or not in \$PATH" 1>&2
exit 5
fi
"$GIT_TOOL" rev-parse --is-inside-work-tree >/dev/null 2>&1
status="$?"
if [[ $status -eq 0 ]]; then
TOPDIR=$("$GIT_TOOL" rev-parse --show-toplevel)
fi
export TOPDIR
# usage
#
export USAGE="usage: $0 [-h] [-v level] [-V] [-d topdir]
-h print help message and exit
-v level set verbosity level (def level: 0)
-V print version string and exit
-d topdir set topdir (def: $TOPDIR)
Exit codes:
0 all OK
1 missing links found
2 -h and help string printed or -V and version string printed
3 command line error
4 bash version is too old
6 problems found with or in the topdir or topdir/YYYY directory
7 problems found with or in the entry topdir/YYYY/dir directory
>= 10 internal error
$NAME version: $VERSION"
# fast_dirname - perform dirname(1) without calling a command
#
# This is very similar with dirname(1) except it is much faster.
#
# usage:
# fast_dirname path_name
#
# path to obtain the directory from
#
function fast_dirname
{
local PATH_NAME; # path_name argument to be modified
# parse args
#
if [[ $# -ne 1 ]]; then
echo "$0: ERROR: in fast_dirname: debug_parameters requires 1 arg, found: $#" 1>&2
exit 10
fi
PATH_NAME="$1"
# firewall - reject empty paths
#
if [[ -z $PATH_NAME ]]; then
echo "$0: ERROR: in fast_dirname: pathname arg is empty" 1>&2
exit 11
fi
# reduce multiple consecutive /'s to just /
#
while :; do
case "$PATH_NAME" in
*//*) PATH_NAME="${PATH_NAME//\/\//\/}" ;;
*) break ;;
esac
done
# trim any trailing /
#
PATH_NAME=${PATH_NAME%%/}
# case: if we only had /'s return /
#
if [[ -z "$PATH_NAME" ]]; then
echo '/'
return;
fi
# case: PATH_NAME is an absolute path starting with /
#
case "$PATH_NAME" in
/*) echo "${PATH_NAME%/*}"; return ;;
*/*) echo "${PATH_NAME%/*}"; return ;;
*) echo '.'; return ;;
esac
}
# parse command line
#
while getopts :hv:Vd:nN flag; do
case "$flag" in
h) echo "$USAGE" 1>&2
exit 2
;;
v) V_FLAG="$OPTARG"
;;
V) echo "$VERSION"
exit 2
;;
d) TOPDIR="$OPTARG"
;;
\?) echo "$0: ERROR: invalid option: -$OPTARG" 1>&2
echo 1>&2
print_usage 1>&2
exit 3
;;
:) echo "$0: ERROR: option -$OPTARG requires an argument" 1>&2
echo 1>&2
echo "$USAGE" 1>&2
exit 3
;;
*) echo "$0: ERROR: unexpected value from getopts: $flag" 1>&2
echo 1>&2
echo "$USAGE" 1>&2
exit 3
;;
esac
done
# remove the options
#
shift $(( OPTIND - 1 ));
#
if [[ $V_FLAG -ge 5 ]]; then
echo "$0: debug[5]: file argument count: $#" 1>&2
fi
#
# verify arg count and parse args
#
export TOOL
case "$#" in
0) ;;
*) echo "$0: ERROR: expected 0 args, found: $#" 1>&2
echo "$USAGE" 1>&2
exit 3
;;
esac
#
if [[ $V_FLAG -ge 1 ]]; then
echo "$0: debug[1]: start scan for missing links" 1>&2
fi
# print running info if verbose
#
# If -v 3 or higher, print exported variables in order that they were exported.
#
if [[ $V_FLAG -ge 3 ]]; then
echo "$0: debug[3]: VERSION=$VERSION" 1>&2
echo "$0: debug[3]: NAME=$NAME" 1>&2
echo "$0: debug[3]: V_FLAG=$V_FLAG" 1>&2
echo "$0: debug[3]: GIT_TOOL=$GIT_TOOL" 1>&2
echo "$0: debug[3]: TOPDIR=$TOPDIR" 1>&2
fi
# cd to topdir
#
if [[ ! -e $TOPDIR ]]; then
echo "$0: ERROR: cannot cd to non-existent path: $TOPDIR" 1>&2
exit 6
fi
if [[ ! -d $TOPDIR ]]; then
echo "$0: ERROR: cannot cd to a non-directory: $TOPDIR" 1>&2
exit 6
fi
export CD_FAILED
if [[ $V_FLAG -ge 5 ]]; then
echo "$0: debug[5]: about to: cd $TOPDIR" 1>&2
fi
cd "$TOPDIR" || CD_FAILED="true"
if [[ -n $CD_FAILED ]]; then
echo "$0: ERROR: cd $TOPDIR failed" 1>&2
exit 6
fi
if [[ $V_FLAG -ge 3 ]]; then
echo "$0: debug[3]: now in directory: $(/bin/pwd)" 1>&2
fi
# create a temporary missing link error message file
#
export TMP_MISSING_LINK=".$NAME.$$.missing_link.md"
if [[ $V_FLAG -ge 3 ]]; then
echo "$0: debug[3]: temporary missing link error message file: $TMP_MISSING_LINK" 1>&2
fi
if [[ -z $NOOP ]]; then
trap 'rm -f $TMP_MISSING_LINK; exit' 0 1 2 3 15
rm -f "$TMP_MISSING_LINK"
if [[ -e $TMP_MISSING_LINK ]]; then
echo "$0: ERROR: cannot remove temporary missing link error message file: $TMP_MISSING_LINK" 1>&2
exit 12
fi
:> "$TMP_MISSING_LINK"
if [[ ! -e $TMP_MISSING_LINK ]]; then
echo "$0: ERROR: cannot create temporary missing link error message file: $TMP_MISSING_LINK" 1>&2
exit 13
fi
elif [[ $V_FLAG -ge 3 ]]; then
echo "$0: debug[3]: because of -n, temporary missing link error message file is not used: $TMP_MISSING_LINK" 1>&2
fi
# collect markdown links
#
# Here be extended regular expression magic dragons! :-)
#
# We will try to explain, as best as we can, these complex regular expressions.
#
# After grep of markdown files (files in sorted dictionary order) for markdown line lines, we sed:
#
# # remove any "[some string]" that is not immediately followed by "("
#
# -e 's/\[[^]]*\]([^(])/\1/' \
#
# # remove any trialing "[followed by text without a closing bracket"
#
# -e 's/\[[^]]*$//' \
#
# Then processing the second file (after the filename field) we sed:
#
# # remove any leading "..non-[-stuff..["
#
# -e 's/^[^[]()+\[/[/' \
#
# # replace "beginning text stuff](" with "[text stuff]("
# # because the previous line might have ended with "[beginning"
#
# -e 's/^([^][]*\]\()/[\1/g' \
#
# # remove any "[..non-]-stuff..][..more-non-]-stuff..]"
#
# -e 's/(\[[^][]*\])+([^(])/\2/g' \
#
# # remove any non-link before the first "[some string](path)"
#
# -e 's/^[^][]+(\[[^]]*\]\([^(]*\))/\1/' \
#
# # remove any final "[..non-]-stuff..$"
#
# -e 's/\[[^]]*$//' \
#
# # remove any final "(..non-)-stuff..)..non-[-stuff.."
#
# -e 's/(\([^)]*\))[^[]*$/\1/' \
#
# # remove any trailing non-[-text after the final "[some string](path)"
#
# -e 's/(\[[^]]*\]\([^(]*\))[^[]+$/\1/' \
#
# # replace ")..non-open-bracket-stuff.[" with ") ["
#
# -e 's/\)[^[]*\[/) [/g' \
#
# # replace "[some string](apath) [other string](bpath)" with two lines:
# #
# # "[some string](apath)"
# # "[other string](bpath)"
#
# -e 's/(\[[^]]*\]\([^(]*\))/\1\n/g' \
#
# # remove blank and empty lines
#
# -e '/^\s*$/d' \
#
# Then pipe the lines into another sed:
#
# # replace multiple space with a single space
#
# -e 's/ +/ /g' \
#
# # remove the leading "[pseudo title]("
#
# -e 's/\[[^]]*\]\(//' \
#
# # remove trailing ")":
#
# -e 's/\)$//' \
#
# # remove and trailing #name
#
# -e 's/#.*$//' \
#
# # remove any leading whitespace
#
# -e 's/^ //' \
#
# # remove blank and empty lines
#
# -e '/^\s*$/d' \
#
# # delete all http: and https: URLs
#
# -e '/^https?:/d' \
#
# # delete all mailto: URLs
#
# -e '/^mailto:/d' \
#
#
# -e 's;%%DOCROOT_SLASH%%/*;/;' \
#
# # add current directory in front of absolute paths
#
# -e "s;^/;$PWD;" \
#
# # add current directory followed by / in front of relative paths
#
# -e "s;^([^/]);$PWD/\1;" \
#
# # convert "%%REPO_URL%%/" into TOPDIR
#
# -e "s;%%REPO_URL%%/*;$TOPDIR/;" \
#
# # convert "%%DOCROOT_SLASH%%" into TOPDIR
#
# -e "s;%%DOCROOT_SLASH%%/*;$TOPDIR/;" \
#
# # relative paths have the directory of the markdown file added to them
#
# -e "s;^([^/]);$TOPDIR/$MD_DIR/\1;" \
#
# # delete all lines containing "%%TOKEN%%" as this is a just a test/example token
#
# -e '/%%TOKEN%%/d' \
#
# At this point in the pipe, we have absolute /-based paths to markdown linked local files.
# We test if those file exist, and if not report a problem in the form:
#
# # Missing file linked in: markdown_file_name.md
# # Markdown line: ..the markdown line containing the line..
# /missing/filename
#
find . -name '*.md' ! -name markdown.md ! -path './tmp/*' -print |
LANG=C sort -d |
xargs grep '\]([^)][^)]*)' /dev/null |
sed -E \
-e 's;^\.\/;;' \
-e 's/^([^:]+):\s*/\1 /' \
|
while read -r MD_PATH MD_LINE; do
# note directory containing the markdown file
#
MD_DIR=$(fast_dirname "$MD_PATH")
export MD_DIR
# extract markdown parts from the given markdown file
#
echo "$MD_LINE" |
sed -E \
-e 's/^[^[]()+\[/[/' \
-e 's/^([^][]*\]\()/[\1/g' \
-e 's/(\[[^][]*\])+([^(])/\2/g' \
-e 's/^[^][]+(\[[^]]*\]\([^(]*\))/\1/' \
-e 's/\[[^]]*$//' \
-e 's/(\([^)]*\))[^[]*$/\1/' \
-e 's/(\[[^]]*\]\([^(]*\))[^[]+$/\1/' \
-e 's/\)[^[]*\[/) [/g' \
-e 's/(\[[^]]*\]\([^(]*\))/\1\n/g' \
-e '/^\s*$/d' \
|
sed -E \
-e 's/ +/ /g' \
-e 's/\[[^]]*\]\(//' \
-e 's/\)$//' \
-e 's/#.*$//' \
-e 's/^ //' \
-e '/^\s*$/d' \
-e '/^https?:/d' \
-e '/^mailto:/d' \
-e "s;%%REPO_URL%%/*;$TOPDIR/;" \
-e "s;%%DOCROOT_SLASH%%/*;$TOPDIR/;" \
-e "s;^([^/]);$TOPDIR/$MD_DIR/\1;" \
-e '/%%TOKEN%%/d' \
|
# write to stderr, missing file messages
#
# The absolute path is written to stderr, while
# info about the possible cause is written to stderr with lines starting with #
#
# We output exact 4 lines per missing link.
#
while read -r ABS_LOCAL_FILE_PATH; do
if [[ ! -e $ABS_LOCAL_FILE_PATH ]]; then
echo "# Missing file linked in: $MD_PATH"
echo "# Markdown line: $MD_LINE"
echo "$ABS_LOCAL_FILE_PATH"
echo
fi
done
done > "$TMP_MISSING_LINK"
# count the missing links
#
MISSING_LINK_COUNT=$(wc -l < "$TMP_MISSING_LINK" | tr -d ' ')
export MISSING_LINK_COUNT
((MISSING_LINK_COUNT=MISSING_LINK_COUNT/4))
# report on any missing links
#
if [[ -s $TMP_MISSING_LINK ]]; then
cat "$TMP_MISSING_LINK" 1>&2
fi
# All Done!!! -- Jessica Noll, Age 2
#
if [[ -s $TMP_MISSING_LINK ]]; then
echo "$0: ERROR: $MISSING_LINK_COUNT missing link(s) found" 1>&2
exit 1
fi
if [[ $V_FLAG -ge 1 ]]; then
echo "$0: debug[1]: $MISSING_LINK_COUNT missing link(s) found" 1>&2
fi
exit 0
+18
View File
@@ -409,6 +409,24 @@ repo</a>.</p>
<p>Generate the list of files in the entry’s manifest, <code>.entry.json</code>.</p>
<p>For example:</p>
<pre><code> awk -f bin/filelist.entry.json.awk 2020/ferguson1/.entry.json</code></pre>
<h3 id="find-missing-links.sh"><a href="../bin/find-missing-links.sh">find-missing-links.sh</a></h3>
<p>Find all markdown links to local files that do not exist.</p>
<p>This tool does <strong>NOT</strong> check of a remote URL exists.
This tool only checks on links to local files.</p>
<p>This tool does <strong>NOT</strong> check links into a given place in a file.
This tool only checks that local files linked by markdown exist.</p>
<p>This tool does <strong>NOT</strong> check HTML file links.
This tool only checks markdown based links.</p>
<p>Usage:</p>
<pre><code> bin/find-missing-links.sh -v 1</code></pre>
<p>If no missing links are found, this tool exits 0 with no output
(debug messages not withstanding), otherwise this tool will exit non-zero.</p>
<p>NOTE: If the markdown link is malformed, this tool
might generate an error about a file that does exist.
If this tool claims that a file is missing that does exist,
look for a malformed markdown line and/or use of markdown
that is <strong>NOT</strong> an IOCCC markdown best practice.</p>
<p>See <a href="markdown.html">IOCCC markdown best practices</a> for more info.</p>
<h3 id="gen-authors.sh"><a href="../bin/gen-authors.sh">gen-authors.sh</a></h3>
<p>Generate the top level <code>/authors.html</code> page.</p>
<p>Usage:</p>
+141 -140
View File
File diff suppressed because it is too large. Load diff
+140 -140
View File
File diff suppressed because it is too large. Load diff
+6 -6
View File
@@ -1981,7 +1981,7 @@ remarks and always the author’s or authors’ remarks, you look at the origina
code. When the entry source code is called <code>prog.c</code> the original code is in
<code>prog.orig.c</code>; otherwise it is <code>dirname.orig.c</code>. For instance one of Landon’s all
time favourite entries is <a href="1984/mullender/index.html">1984/mullender</a> and the
original code is in <a href="1984/mullender/mullender.orig.c">mullender.orig.c</a>. In
original code is in <a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/1984/mullender/mullender.orig.c">mullender.orig.c</a>. In
some cases, such as <code>1984/mullender</code>, the original code is the same as the code
as no changes were made (there is an alt version for systems that are not
VAX-11/PDP-11, however).</p>
@@ -2219,7 +2219,7 @@ longer fit within the year’s size restrictions. Invariably the length of colum
and/or number of rows have also changed.</p>
<p>The <code>winner.orig.c</code> file contains the original source code that was
subjected to rule 2 of the given IOCCC. You may also wish to see
the <a href="archive">/archive</a> directory where you can find all the
the <a href="archive">archive</a> directory where you can find all the
original winning entries as compressed tar files for a given year.</p>
<p>In some cases the entry may have abused rule 2 and declared an
“abuse of the rules” (although now blatant abuse of the rules to
@@ -2314,7 +2314,7 @@ author.</p>
<p>The latter form is in case there are more than one anonymous author in a given
year.</p>
<p>NOTE: even if the directory name is not <code>anonymous</code> the above rules apply as in
in the case of <a href="2005/anon/anon.c">2005/anon</a>.</p>
in the case of <a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2005/anon/anon.c">2005/anon</a>.</p>
<p>Anonymous <code>author_handle</code>’s match this regexp:</p>
<pre><code> Anonymous_[0-9][0-9][0-9][0-9][.0-9]*$</code></pre>
<p>See <a href="#fix_author">FAQ 5.5</a> for information about how to update
@@ -2619,7 +2619,7 @@ of IOCCC years.</p>
of the IOCCC entry directories for a given year. For example, see the <a href=".1984/.year">1984/.year</a> file.</p>
<p>Under each IOCCC entry directory, you will find a <code>.path</code> file.
These files contain the directory path from the top directory.
For example see <a href="1984/anonymous/.path">1984/anonymous/.path</a>.</p>
For example see <a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/1984/anonymous/.path">1984/anonymous/.path</a>.</p>
<p>The .top, .year and .path files are generated from the top level Makefile, by:</p>
<pre><code> make genpath</code></pre>
<div id="faq6_9">
@@ -2735,7 +2735,7 @@ it will be that. For instance using the above example you might do:</p>
<h4 id="making-changes-fixes-etc.">Making changes, fixes etc.</h4>
<p>Here you must use your wits, knowledge, creativity and whatever else you have.
Let’s say that Cody wants to update his file
<a href="2020/ferguson1/play.sh">/2020/ferguson1/play.sh</a> script. He would open it in
<a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2020/ferguson1/play.sh">2020/ferguson1/play.sh</a> script. He would open it in
his editor of choice (in his case vim) and make the changes. He would then make
sure (as there is a last updated date) to update the last updated date. For
instance he might add the following:</p>
@@ -2767,7 +2767,7 @@ with your ssh key. To do this you need to do:</p>
<p>Now you’d be ready to make your commits.</p>
<p>Before doing anything else, however, a new branch needs to be created.
Continuing the example above for
<a href="2020/ferguson1/play.sh">2020/ferguson1/play.sh</a>, it might be that:</p>
<a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2020/ferguson1/play.sh">2020/ferguson1/play.sh</a>, it might be that:</p>
<pre><code> git checkout -B human-snakes</code></pre>
<p>This would change the branch to the newly created branch <code>human-snakes</code> branch.
Now Cody could commit the changes:</p>
+6 -6
View File
@@ -2344,7 +2344,7 @@ remarks and always the author's or authors' remarks, you look at the original
code. When the entry source code is called `prog.c` the original code is in
`prog.orig.c`; otherwise it is `dirname.orig.c`. For instance one of Landon's all
time favourite entries is [1984/mullender](1984/mullender/index.html) and the
original code is in [mullender.orig.c](1984/mullender/mullender.orig.c). In
original code is in [mullender.orig.c](%%REPO_URL%%/1984/mullender/mullender.orig.c). In
some cases, such as `1984/mullender`, the original code is the same as the code
as no changes were made (there is an alt version for systems that are not
VAX-11/PDP-11, however).
@@ -2675,7 +2675,7 @@ and/or number of rows have also changed.
The `winner.orig.c` file contains the original source code that was
subjected to rule 2 of the given IOCCC. You may also wish to see
the [/archive](archive) directory where you can find all the
the [archive](archive) directory where you can find all the
original winning entries as compressed tar files for a given year.
In some cases the entry may have abused rule 2 and declared an
@@ -2817,7 +2817,7 @@ The latter form is in case there are more than one anonymous author in a given
year.
NOTE: even if the directory name is not `anonymous` the above rules apply as in
in the case of [2005/anon](2005/anon/anon.c).
in the case of [2005/anon](%%REPO_URL%%/2005/anon/anon.c).
Anonymous `author_handle`'s match this regexp:
@@ -3352,7 +3352,7 @@ of the IOCCC entry directories for a given year. For example, see the [1984/.ye
Under each IOCCC entry directory, you will find a `.path` file.
These files contain the directory path from the top directory.
For example see [1984/anonymous/.path](1984/anonymous/.path).
For example see [1984/anonymous/.path](%%REPO_URL%%/1984/anonymous/.path).
The .top, .year and .path files are generated from the top level Makefile, by:
@@ -3513,7 +3513,7 @@ You're ready to make your changes now!
Here you must use your wits, knowledge, creativity and whatever else you have.
Let's say that Cody wants to update his file
[/2020/ferguson1/play.sh](2020/ferguson1/play.sh) script. He would open it in
[2020/ferguson1/play.sh](%%REPO_URL%%/2020/ferguson1/play.sh) script. He would open it in
his editor of choice (in his case vim) and make the changes. He would then make
sure (as there is a last updated date) to update the last updated date. For
instance he might add the following:
@@ -3563,7 +3563,7 @@ Now you'd be ready to make your commits.
Before doing anything else, however, a new branch needs to be created.
Continuing the example above for
[2020/ferguson1/play.sh](2020/ferguson1/play.sh), it might be that:
[2020/ferguson1/play.sh](%%REPO_URL%%/2020/ferguson1/play.sh), it might be that:
``` <!---sh-->
+30 -11
View File
@@ -473,11 +473,24 @@ unquoted attribute values.</p>
<pre><code> &lt;del&gt;...&lt;/del&gt;</code></pre>
<h2 id="do-not-use-tt-html-elements">Do not use tt HTML elements</h2>
<p>Please do not use the tt HTML elements:</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a> <span class="dt">&lt;</span><span class="kw">tt</span><span class="dt">&gt;</span>The HTML 5 obsolete tt element is obsolete<span class="dt">&lt;/</span><span class="kw">tt</span><span class="dt">&gt;</span></span></code></pre></div>
<div class="sourceCode" id="cb16"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a> <span class="dt">&lt;</span><span class="kw">tt</span><span class="dt">&gt;</span>The HTML 5 obsolete tt element is obsolete<span class="dt">&lt;/</span><span class="kw">tt</span><span class="dt">&gt;</span> <span class="er">&lt;</span>=== no thank you</span></code></pre></div>
<p>Instead use either a monospaced span:</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a> <span class="dt">&lt;</span><span class="kw">span</span><span class="ot"> style</span><span class="op">=</span><span class="st">&quot;font-family: monospace;&quot;</span><span class="dt">&gt;</span>Use of monospaced font is one option<span class="dt">&lt;/</span><span class="kw">span</span><span class="dt">&gt;</span></span></code></pre></div>
<p>Or better and easier still, use an inline markdown code block:</p>
<pre><code> `inline markdown code block is easier and much better`</code></pre>
<h2 id="do-not-use-un-indented-code-clocks">Do not use un-indented code clocks</h2>
<p>Please do not start code blocks at the left-hand edge.</p>
<pre><code>```
This code block &lt;=== no thank you
is not indendted
```
```
We request that you indent the code block by 4 spaces:
</code></pre>
<pre><code> This code block
is intented 4 spaces</code></pre>
<p>````</p>
<h2 id="do-not-add-trailing-slash-on-void-html-elements">Do not add trailing slash on void HTML elements</h2>
<p>Please do not use trailing slash on <a href="https://github.com/validator/validator/wiki/Markup-»-Void-elements">void HTML
elements</a>.</p>
@@ -506,18 +519,24 @@ tags</a>.</p>
<p>Markdown links that end in “))” complicate parsing and sometimes lead
to incorrect URLs or file paths.</p>
<p>Instead of:</p>
<pre><code>[some text](https://example.com/foo_(bar)) &lt;=== no thank you</code></pre>
<pre><code> [some text](https://example.com/foo_(bar)) &lt;=== no thank you</code></pre>
<p>Use:</p>
<pre><code>[some text](https://example.com/foo_&amp;#x28;bar&amp;#x29;)</code></pre>
<pre><code> [some text](https://example.com/foo_&amp;#x28;bar&amp;#x29;)</code></pre>
<p>Instead of:</p>
<pre><code>This thing ([some text](some/path)) is not ideal. &lt;=== no thank you
``
Use:
</code></pre>
<p>This thing, <a href="some/path">some text</a>, is better.
```
<!-- AFTER: last line of markdown file: markdown.md --></p>
<pre><code> This thing ([some text](some/path)) is not ideal. &lt;=== no thank you</code></pre>
<p>Use:</p>
<pre><code> This thing, [some text](some/path), is better.</code></pre>
<h2 id="do-not-put-s-or-markdown-link-titles">Do not put (‘s or )’ markdown link titles</h2>
<p>Please do not use parenthesis inside the markdown link titles.</p>
<p>Instead of:</p>
<pre><code> [some (text)](https://example.com/cyrds) &lt;=== no thank you</code></pre>
<p>Use:</p>
<pre><code> [some &amp;#x28;text&amp;#x29;](https://example.com/cyrds)</code></pre>
<p>Instead of:</p>
<pre><code> [ls(1)](https://example.com/ls-man-page.1) &lt;=== no thank you</code></pre>
<p>Use:</p>
<pre><code> [ls&amp;#x28;1&amp;#x29;](https://example.com/ls-man-page.1)</code></pre>
<!-- AFTER: last line of markdown file: markdown.md -->
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<!-- START: this line starts content from: inc/after-content.default.html -->
+57 -6
View File
@@ -183,7 +183,7 @@ Use instead:
Please do not use the tt HTML elements:
```html
<tt>The HTML 5 obsolete tt element is obsolete</tt>
<tt>The HTML 5 obsolete tt element is obsolete</tt> <=== no thank you
```
Instead use either a monospaced span:
@@ -199,6 +199,27 @@ Or better and easier still, use an inline markdown code block:
```
## Do not use un-indented code clocks
Please do not start code blocks at the left-hand edge.
````
```
This code block <=== no thank you
is not indendted
```
```
We request that you indent the code block by 4 spaces:
````
```
This code block
is intented 4 spaces
```
````
## Do not add trailing slash on void HTML elements
Please do not use trailing slash on [void HTML
@@ -251,6 +272,7 @@ Instead use just:
etc.
## Do not end markdown links in ))
Please do not end a markdown links with a double closed parenthesis "))".
@@ -261,23 +283,52 @@ to incorrect URLs or file paths.
Instead of:
```
[some text](https://example.com/foo_(bar)) <=== no thank you
[some text](https://example.com/foo_(bar)) <=== no thank you
```
Use:
```
[some text](https://example.com/foo_&#x28;bar&#x29;)
[some text](https://example.com/foo_&#x28;bar&#x29;)
```
Instead of:
```
This thing ([some text](some/path)) is not ideal. <=== no thank you
``
This thing ([some text](some/path)) is not ideal. <=== no thank you
```
Use:
```
This thing, [some text](some/path), is better.
This thing, [some text](some/path), is better.
```
## Do not put ('s or )' markdown link titles
Please do not use parenthesis inside the markdown link titles.
Instead of:
```
[some (text)](https://example.com/cyrds) <=== no thank you
```
Use:
```
[some &#x28;text&#x29;](https://example.com/cyrds)
```
Instead of:
```
[ls(1)](https://example.com/ls-man-page.1) <=== no thank you
```
Use:
```
[ls&#x28;1&#x29;](https://example.com/ls-man-page.1)
```
+1 -1
View File
@@ -15,7 +15,7 @@ Nearly all of the [temp-test-ioccc web site](https://ioccc-src.github.io/temp-te
web site has undergone editorial review. Nearly all [IOCCC winning entries](years.html)
compile on modern systems and many have `try.sh` scripts to help you run them.
For those that cannot compile and/or do not work, we have made a
[Bugs and (Mis)features](bugs.html) page.
[Bugs and &#x28;Mis&#x29;features](bugs.html) page.
We have made nearly 4823 changes to date!
+1 -1
View File
@@ -387,7 +387,7 @@
&quot;no_comment&quot; : &quot;mandatory comment: because comments were removed from the original JSON spec&quot;,
&quot;IOCCC_status_version&quot; : &quot;1.0 2024-03-09&quot;,
&quot;contest_status&quot; : &quot;closed&quot;,
&quot;news_update&quot; : &quot;2024-04-21T22:08:12+00:00&quot;,
&quot;news_update&quot; : &quot;2024-04-28T06:28:19+00:00&quot;,
&quot;status_update&quot; : &quot;2024-03-31T05:02:06+00:00&quot;
}</code></pre>
+1 -1
View File
@@ -2,6 +2,6 @@
"no_comment" : "mandatory comment: because comments were removed from the original JSON spec",
"IOCCC_status_version" : "1.0 2024-03-09",
"contest_status" : "closed",
"news_update" : "2024-04-21T22:08:12+00:00",
"news_update" : "2024-04-28T06:28:19+00:00",
"status_update" : "2024-03-31T05:02:06+00:00"
}
+146 -146
View File
File diff suppressed because it is too large. Load diff
+146 -146
View File
File diff suppressed because it is too large. Load diff
+11
View File
@@ -348,6 +348,17 @@ Examples:
```
## [md-chk-paths.sh](%%DOCROOT_SLASH%%tmp/md-chk-paths.sh)
Print full directories of local (non-remote URL) markdown paths.
Usage:
``` <!---sh-->
tmp/md-chk-paths.sh
```
## [md-links.sh](%%DOCROOT_SLASH%%tmp/md-links.sh)
For all markdown files, print markdown links.
+463
View File
@@ -0,0 +1,463 @@
#!/usr/bin/env bash
#
# md-chk-paths.sh - print local file paths referenced in markdown links
#
# For all markdown files, print markdown links that are local.
# We ignore URLs that start with "http:" or "https:".
# We ignore links that are internal to the file (i.e., "#name").
# We strip all "#name" from paths.
#
# Copyright (c) 2024 by Landon Curt Noll. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and
# its documentation for any purpose and without fee is hereby granted,
# provided that the above copyright, this permission notice and text
# this comment, and the disclaimer below appear in all of the following:
#
# supporting documentation
# source copies
# source works derived from this source
# binaries derived from this source or from derived source
#
# LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
# EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
# USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
#
# chongo (Landon Curt Noll, http://www.isthe.com/chongo/index.html) /\oo/\
#
# Share and enjoy! :-)
# firewall - run only with a bash that is version 5.1.8 or later
#
# The "/usr/bin/env bash" command must result in using a bash that
# is version 5.1.8 or later.
#
# We could relax this version and insist on version 4.2 or later. Versions
# of bash between 4.2 and 5.1.7 might work. However, to be safe, we will require
# bash version 5.1.8 or later.
#
# WHY 5.1.8 and not 4.2? This safely is done because macOS Homebrew bash we
# often use is "version 5.2.26(1)-release" or later, and the RHEL Linux bash we
# use often use is "version 5.1.8(1)-release" or later. These versions are what
# we initially tested. We recommend you either upgrade bash or install a newer
# version of bash and adjust your $PATH so that "/usr/bin/env bash" finds a bash
# that is version 5.1.8 or later.
#
# NOTE: The macOS shipped, as of 2024 March 15, a version of bash is something like
# bash "version 3.2.57(1)-release". That macOS shipped version of bash
# will NOT work. For users of macOS we recommend you install Homebrew,
# (see https://brew.sh), and then run "brew install bash" which will
# typically install it into /opt/homebrew/bin/bash, and then arrange your $PATH
# so that "/usr/bin/env bash" finds "/opt/homebrew/bin" (or whatever the
# Homebrew bash is).
#
# NOTE: And while MacPorts might work, we noticed a number of subtle differences
# with some of their ported tools to suggest you might be better off
# with installing Homebrew (see https://brew.sh). No disrespect is intended
# to the MacPorts team as they do a commendable job. Nevertheless we ran
# into enough differences with MacPorts environments to suggest you
# might find a better experience with this tool under Homebrew instead.
#
if [[ -z ${BASH_VERSINFO[0]} ||
${BASH_VERSINFO[0]} -lt 5 ||
${BASH_VERSINFO[0]} -eq 5 && ${BASH_VERSINFO[1]} -lt 1 ||
${BASH_VERSINFO[0]} -eq 5 && ${BASH_VERSINFO[1]} -eq 1 && ${BASH_VERSINFO[2]} -lt 8 ]]; then
echo "$0: ERROR: bash version needs to be >= 5.1.8: $BASH_VERSION" 1>&2
echo "$0: Warning: bash version >= 4.2 might work but 5.1.8 was the minimum we tested" 1>&2
echo "$0: Notice: For macOS users: install Homebrew (see https://brew.sh), then run" \
""brew install bash" and then modify your \$PATH so that \"#!/usr/bin/env bash\"" \
"finds the Homebrew installed (usually /opt/homebrew/bin/bash) version of bash" 1>&2
exit 4
fi
# setup bash file matching
#
# We must declare arrays with -ag or -Ag, and we need loops to "export" modified variables.
# This requires a bash with a version 4.2 or later. See the larger comment above about bash versions.
#
shopt -s nullglob # enable expanded to nothing rather than remaining unexpanded
shopt -u failglob # disable error message if no matches are found
shopt -u dotglob # disable matching files starting with .
shopt -u nocaseglob # disable strict case matching
shopt -u extglob # enable extended globbing patterns
shopt -s globstar # enable ** to match all files and zero or more directories and subdirectories
# set variables referenced in the usage message
#
export VERSION="1.0 2024-04-25"
NAME=$(basename "$0")
export NAME
export V_FLAG=0
GIT_TOOL=$(type -P git)
export GIT_TOOL
if [[ -z "$GIT_TOOL" ]]; then
echo "$0: FATAL: git tool is not installed or not in \$PATH" 1>&2
exit 5
fi
"$GIT_TOOL" rev-parse --is-inside-work-tree >/dev/null 2>&1
status="$?"
if [[ $status -eq 0 ]]; then
TOPDIR=$("$GIT_TOOL" rev-parse --show-toplevel)
fi
export TOPDIR
# usage
#
export USAGE="usage: $0 [-h] [-v level] [-V] [-d topdir]
-h print help message and exit
-v level set verbosity level (def level: 0)
-V print version string and exit
-d topdir set topdir (def: $TOPDIR)
Exit codes:
0 all OK
1 some internal tool exited non-zero
2 -h and help string printed or -V and version string printed
3 command line error
4 bash version is too old
6 problems found with or in the topdir or topdir/YYYY directory
7 problems found with or in the entry topdir/YYYY/dir directory
>= 10 internal error
$NAME version: $VERSION"
# fast_dirname - perform dirname(1) without calling a command
#
# This is very similar with dirname(1) except it is much faster.
#
# usage:
# fast_dirname path_name
#
# path to obtain the directory from
#
function fast_dirname
{
local PATH_NAME; # path_name argument to be modified
# parse args
#
if [[ $# -ne 1 ]]; then
echo "$0: ERROR: in fast_dirname: debug_parameters requires 1 arg, found: $#" 1>&2
exit 10
fi
PATH_NAME="$1"
# firewall - reject empty paths
#
if [[ -z $PATH_NAME ]]; then
echo "$0: ERROR: in fast_dirname: pathname arg is empty" 1>&2
exit 11
fi
# reduce multiple consecutive /'s to just /
#
while :; do
case "$PATH_NAME" in
*//*) PATH_NAME="${PATH_NAME//\/\//\/}" ;;
*) break ;;
esac
done
# trim any trailing /
#
PATH_NAME=${PATH_NAME%%/}
# case: if we only had /'s return /
#
if [[ -z "$PATH_NAME" ]]; then
echo '/'
return;
fi
# case: PATH_NAME is an absolute path starting with /
#
case "$PATH_NAME" in
/*) echo "${PATH_NAME%/*}"; return ;;
*/*) echo "${PATH_NAME%/*}"; return ;;
*) echo '.'; return ;;
esac
}
# parse command line
#
while getopts :hv:Vd:nN flag; do
case "$flag" in
h) echo "$USAGE" 1>&2
exit 2
;;
v) V_FLAG="$OPTARG"
;;
V) echo "$VERSION"
exit 2
;;
d) TOPDIR="$OPTARG"
;;
\?) echo "$0: ERROR: invalid option: -$OPTARG" 1>&2
echo 1>&2
print_usage 1>&2
exit 3
;;
:) echo "$0: ERROR: option -$OPTARG requires an argument" 1>&2
echo 1>&2
echo "$USAGE" 1>&2
exit 3
;;
*) echo "$0: ERROR: unexpected value from getopts: $flag" 1>&2
echo 1>&2
echo "$USAGE" 1>&2
exit 3
;;
esac
done
# remove the options
#
shift $(( OPTIND - 1 ));
#
if [[ $V_FLAG -ge 5 ]]; then
echo "$0: debug[5]: file argument count: $#" 1>&2
fi
#
# verify arg count and parse args
#
export TOOL
case "$#" in
0) ;;
*) echo "$0: ERROR: expected 0 args, found: $#" 1>&2
echo "$USAGE" 1>&2
exit 3
;;
esac
# print running info if verbose
#
# If -v 3 or higher, print exported variables in order that they were exported.
#
if [[ $V_FLAG -ge 3 ]]; then
echo "$0: debug[3]: VERSION=$VERSION" 1>&2
echo "$0: debug[3]: NAME=$NAME" 1>&2
echo "$0: debug[3]: V_FLAG=$V_FLAG" 1>&2
echo "$0: debug[3]: GIT_TOOL=$GIT_TOOL" 1>&2
echo "$0: debug[3]: TOPDIR=$TOPDIR" 1>&2
fi
# cd to topdir
#
if [[ ! -e $TOPDIR ]]; then
echo "$0: ERROR: cannot cd to non-existent path: $TOPDIR" 1>&2
exit 6
fi
if [[ ! -d $TOPDIR ]]; then
echo "$0: ERROR: cannot cd to a non-directory: $TOPDIR" 1>&2
exit 6
fi
export CD_FAILED
if [[ $V_FLAG -ge 5 ]]; then
echo "$0: debug[5]: about to: cd $TOPDIR" 1>&2
fi
cd "$TOPDIR" || CD_FAILED="true"
if [[ -n $CD_FAILED ]]; then
echo "$0: ERROR: cd $TOPDIR failed" 1>&2
exit 6
fi
if [[ $V_FLAG -ge 3 ]]; then
echo "$0: debug[3]: now in directory: $(/bin/pwd)" 1>&2
fi
# collect markdown links
#
# Here be extended regular expression magic dragons! :-)
#
# We will try to explain, as best as we can, these complex regular expressions.
#
# After grep of markdown files (files in sorted dictionary order) for markdown line lines, we sed:
#
# # remove any "[some string]" that is not immediately followed by "("
#
# -e 's/\[[^]]*\]([^(])/\1/' \
#
# # remove any trialing "[followed by text without a closing bracket"
#
# -e 's/\[[^]]*$//' \
#
# Then processing the second file (after the filename field) we sed:
#
# # remove any leading "..non-[-stuff..["
#
# -e 's/^[^[]()+\[/[/' \
#
# # replace "beginning text stuff](" with "[text stuff]("
# # because the previous line might have ended with "[beginning"
#
# -e 's/^([^][]*\]\()/[\1/g' \
#
# # remove any "[..non-]-stuff..][..more-non-]-stuff..]"
#
# -e 's/(\[[^][]*\])+([^(])/\2/g' \
#
# # remove any non-link before the first "[some string](path)"
#
# -e 's/^[^][]+(\[[^]]*\]\([^(]*\))/\1/' \
#
# # remove any final "[..non-]-stuff..$"
#
# -e 's/\[[^]]*$//' \
#
# # remove any final "(..non-)-stuff..)..non-[-stuff.."
#
# -e 's/(\([^)]*\))[^[]*$/\1/' \
#
# # remove any trailing non-[-text after the final "[some string](path)"
#
# -e 's/(\[[^]]*\]\([^(]*\))[^[]+$/\1/' \
#
# # replace ")..non-open-bracket-stuff.[" with ") ["
#
# -e 's/\)[^[]*\[/) [/g' \
#
# # replace "[some string](apath) [other string](bpath)" with two lines:
# #
# # "[some string](apath)"
# # "[other string](bpath)"
#
# -e 's/(\[[^]]*\]\([^(]*\))/\1\n/g' \
#
# # remove blank and empty lines
#
# -e '/^\s*$/d' \
#
# Then pipe the lines into another sed:
#
# # replace multiple space with a single space
#
# -e 's/ +/ /g' \
#
# # remove the leading "[pseudo title]("
#
# -e 's/\[[^]]*\]\(//' \
#
# # remove trailing ")":
#
# -e 's/\)$//' \
#
# # remove and trailing #name
#
# -e 's/#.*$//' \
#
# # remove any leading whitespace
#
# -e 's/^ //' \
#
# # remove blank and empty lines
#
# -e '/^\s*$/d' \
#
# # delete all http: and https: URLs
#
# -e '/^https?:/d' \
#
# # delete all mailto: URLs
#
# -e '/^mailto:/d' \
#
#
# -e 's;%%DOCROOT_SLASH%%/*;/;' \
#
# # add current directory in front of absolute paths
#
# -e "s;^/;$PWD;" \
#
# # add current directory followed by / in front of relative paths
#
# -e "s;^([^/]);$PWD/\1;" \
#
# # convert "%%REPO_URL%%/" into TOPDIR
#
# -e "s;%%REPO_URL%%/*;$TOPDIR/;" \
#
# # convert "%%DOCROOT_SLASH%%" into TOPDIR
#
# -e "s;%%DOCROOT_SLASH%%/*;$TOPDIR/;" \
#
# # relative paths have the directory of the markdown file added to them
#
# -e "s;^([^/]);$TOPDIR/$MD_DIR/\1;" \
#
# # delete all lines containing "%%TOKEN%%" as this is a just a test/example token
#
# -e '/%%TOKEN%%/d' \
#
# At this point in the pipe, we have absolute /-based paths to markdown linked local files.
# We test if those file exist, and if not report a problem in the form:
#
# # Missing file linked in: markdown_file_name.md
# # Markdown line: ..the markdown line containing the line..
# /missing/filename
#
find . -name '*.md' ! -name markdown.md ! -path './tmp/*' -print |
LANG=C sort -d |
xargs grep '\]([^)][^)]*)' /dev/null |
sed -E \
-e 's;^\.\/;;' \
-e 's/^([^:]+):\s*/\1 /' \
|
while read -r MD_PATH MD_LINE; do
# note directory containing the markdown file
#
MD_DIR=$(fast_dirname "$MD_PATH")
export MD_DIR
# extract markdown parts from the given markdown file
#
echo "$MD_LINE" |
sed -E \
-e 's/^[^[]()+\[/[/' \
-e 's/^([^][]*\]\()/[\1/g' \
-e 's/(\[[^][]*\])+([^(])/\2/g' \
-e 's/^[^][]+(\[[^]]*\]\([^(]*\))/\1/' \
-e 's/\[[^]]*$//' \
-e 's/(\([^)]*\))[^[]*$/\1/' \
-e 's/(\[[^]]*\]\([^(]*\))[^[]+$/\1/' \
-e 's/\)[^[]*\[/) [/g' \
-e 's/(\[[^]]*\]\([^(]*\))/\1\n/g' \
-e '/^\s*$/d' \
|
sed -E \
-e 's/ +/ /g' \
-e 's/\[[^]]*\]\(//' \
-e 's/\)$//' \
-e 's/#.*$//' \
-e 's/^ //' \
-e '/^\s*$/d' \
-e '/^https?:/d' \
-e '/^mailto:/d' \
-e "s;%%REPO_URL%%/*;$TOPDIR/;" \
-e "s;%%DOCROOT_SLASH%%/*;$TOPDIR/;" \
-e "s;^([^/]);$TOPDIR/$MD_DIR/\1;" \
-e '/%%TOKEN%%/d' \
|
while read -r ABS_LOCAL_FILE_PATH; do
if [[ ! -e $ABS_LOCAL_FILE_PATH ]]; then
echo "# Missing file linked in: $MD_PATH" 1>&2
echo "# Markdown line: $MD_LINE" 1>&2
echo "$ABS_LOCAL_FILE_PATH" 1>&2
fi
done
done
# All Done!!! -- Jessica Noll, Age 2
#
exit 0