]> git.plutz.net Git - shellwiki/commitdiff
slideshow integration: adapted clickslide for markdown output
authorPaul Hänsch <paul@plutz.net>
Sat, 26 Sep 2026 12:33:07 +0000 (14:33 +0200)
committerPaul Hänsch <paul@plutz.net>
Sat, 26 Sep 2026 12:33:07 +0000 (14:33 +0200)
handlers/70_slideshow.sh
themes/slideshow.css

index 066aa888bd43a8ffaa147cbe722e9c2e13e5f310..15349ccaf927c1c3db12436b13f78223a152e1b7 100755 (executable)
@@ -32,101 +32,103 @@ cat <<-EOF
 
 page="${PATH_INFO%\[*\]}"
 wiki "$page" | {
-  read -r line
-  prev='' next='' idoff=0
+  # slide previous ID, slide current ID, slide number
+  sl_pre='' sl_cur='' sl_num=0
   depth=0 ucdepth=-1
+  stack=''
+  printf '<a href="#" class="toplevel">overview</a>'
 
-  while :; do 
+  # loop over each tag in a line
+  # new lines are only added, when tags from current
+  # line are exhausted
+  read -r line; while :; do 
+    # tag will contain the current tag and preceeding text content
     tag="${tag}${line%%>*}"
   
-    if [ "$line" = "${line%%>*}" ]; then
-      # $line did not contain ">" and thus was added to $tag entirely
-      if ! read -r line; then
+    if [ "$line" = "${line%%>*}" ]; then  # Tag seems to continue into next line
+      if read -r line; then
+        tag="${tag}${BR}"
+        continue
+      else  # input stream has ended
         printf %s\\n "$tag"
         break
       fi
-      tag="${tag}${BR}"
-    else
-      # $line is shortened by segment added to $tag
-      line="${line#*>}"
+    else  # First tag will be processed and remainder of line kept for next loop
       tag="${tag}>"
+      line="${line#*>}"
     fi
 
     case $tag in
-      *\<section\ class=\"h1\"\ *id=\"?*\"*\>*)  # Count slide id, insert "next" button
-        prev="$next"
-        next="${tag#*<section }" next="${next#*id=\"}" next="${next%\"*}"
-        next="autoslide${idoff}"
-        idoff="$((idoff + 1))"
-        printf '%s<a class="nextslide" href="#%s">next</a><div class="slide" count="%i" id="%s" %s' \
-          "${tag%<section *}" "$next" "$idoff" "$next" "${tag#*<section }"
-        tag='' depth=$((depth + 1)) sldepth=$depth
-        ;;
-      *\<section\ class=\"h1\"\ *\>*)
-        prev="$next"
-        next="autoslide${idoff}"
-        idoff="$((idoff + 1))"
-        printf '%s<a class="nextslide" href="#%s">next</a><div class="slide" count="%i" id="%s" %s' \
-          "${tag%<section*}" "$next" "$idoff" "$next" "${tag#*<section}"
-        tag='' depth=$((depth + 1)) sldepth=$depth
-        ;;
-      *\<section\ class=\"h2\"\ *id=\"?*\"*\>*)  # Count slide id, insert "next" button
-        prev="$next"
-        next="${tag#*<section }" next="${next#*id=\"}" next="${next%\"*}"
-        next="autoslide${idoff}"
-        idoff="$((idoff + 1))"
-        if [ $depth -eq $sldepth ]; then
-          printf '%s</div><a class="prevslide" href="#%s">previous</a>' \
-            "${tag%<section*}" "$prev"
+      *\<section\ class=\"h1*\"\ id=\"?*\"\>)  # Count slide id, insert "next" button
+        if [ "$stack" = "" ]; then
+          stack="${stack},section"
+          sl_pre="$sl_cur"
+          sl_cur="${tag#*<section class=* id=\"}" sl_cur="${sl_cur%\">}"
+          sl_num="$((sl_num + 1))"
+
+          printf '%s<a class="nextslide" href="#%s">next</a>\n<section count="%i" class="slide %s' \
+            "${tag%<section *}" "$sl_cur" "$sl_num" "${tag#*<section class=\"}"
+
         else
-          printf '%s' "${tag%<section*}"
+          stack="${stack},section"
+          printf '%s' "$tag"
         fi
-        printf '<a class="nextslide" href="#%s">next</a><div class="slide" count="%i" id="%s" %s' \
-          "$next" "$idoff" "$next" "${tag#*<section }"
         tag='' depth=$((depth + 1)) sldepth=$depth
         ;;
-      *\<section\ class=\"h2\"\ *\>*|*\<section\>*)
-        prev="$next"
-        next="autoslide${idoff}"
-        idoff="$((idoff + 1))"
-        if [ $depth -eq $sldepth ]; then
-          printf '%s</div><a class="prevslide" href="#%s">previous</a>' \
-            "${tag%<section*}" "$prev"
+      *\<section\ class=\"h2*\"\ id=\"?*\"\>)  # Count slide id, insert "next" button
+        # *force* unwrapping from containing H1 section
+        if [ "$stack" = ",section" ]; then
+          printf '%s</section>\n<a class="prevslide" href="#%s">previous</a>' \
+            "${tag%<section*}" "$sl_pre"
+          tag="<section ${tag#*<section }"
+          stack="${stack%,section}"
+        fi
+
+        if [ "$stack" = "" ]; then
+          stack="${stack},section"
+          sl_pre="$sl_cur"
+          sl_cur="${tag#*<section class=* id=\"}" sl_cur="${sl_cur%\">}"
+          sl_num="$((sl_num + 1))"
+
+          printf '%s<a class="nextslide" href="#%s">next</a>\n<section count="%i" class="slide %s' \
+            "${tag%<section *}" "$sl_cur" "$sl_num" "${tag#*<section class=\"}"
         else
-          printf '%s' "${tag%<section*}"
+          stack="${stack},section"
+          debug "$stack"
+          printf '%s' "$tag"
         fi
-        printf '<a class="nextslide" href="#%s">next</a><div class="slide" count="%i" id="%s" %s' \
-          "$next" "$idoff" "$next" "${tag#*<section}"
         tag='' depth=$((depth + 1)) sldepth=$depth
         ;;
-      *\</section\>*)  # Insert "previous" button
-        if [ $depth -eq $sldepth ]; then
-          printf '%s</div><a class="prevslide" href="#%s">previous</a>%s' \
-            "${tag%</section>*}" "$prev" "${tag#*</section>}"
+      *\</section\>)  # Insert "previous" button
+        if [ "$stack" = ",section" ]; then
+          printf '%s\n<a class="prevslide" href="#%s">previous</a>' \
+            "${tag}" "$sl_pre"
+        elif [ "$stack" = "" ]; then
+          :
         else
-          printf %s "${tag%</section>*}"
+          printf %s "${tag}"
         fi
+        stack="${stack%,section}"
         tag='' depth=$((depth - 1))
         ;;
-      # *\<body*\>*)  # Insert toplevel link
-      #   printf '%s<a href="#" class="toplevel">overview</a>' "$tag"
-      #   tag='' depth=$((depth + 1))
-      #   ;;
-      # *\</body*\>*)  # Insert total slide count
-      #   printf '<span class="count">%i</span>%s' "$idoff" "$tag"
-      #   tag='' depth=$((depth - 1))
-      #   ;;
-      *\<*class=\"uncover\"*\>*)  # Insert checkboxes in "uncover" lists
-        #printf '%s<li></li>' "$tag"
+      *\<*\ class=\"uncover\"*\>)  # Insert checkboxes in "uncover" lists
+        # printf '%s<li></li>' "$tag"
         printf '%s' "$tag"
+        tag="${tag#*<}" tag="${tag%%[ >]*}"
+        stack="${stack},${tag}"
         tag='' depth=$((depth + 1))
         ucdepth=$((depth + 1))
         ;;
-      *\</*\>*)
+      *\</*\>)
         printf %s "$tag"
+        stack="${stack%,*}"
         tag='' depth=$((depth - 1))
         [ $depth -lt $ucdepth ] && ucdepth=-1
         ;;
+      *\<*/\>|*\<br\>|*\<hr\>|*\<img\ *\>)
+        printf %s "$tag"
+        tag=''
+        ;;
       *\<*\>*)
         if [ $ucdepth = $depth ]; then
           printf '%s<input type="checkbox" class="uncover"/><%s' "${tag%<*}" "${tag#*<}"
@@ -134,13 +136,15 @@ wiki "$page" | {
           printf %s "$tag"
         fi
         [ "${tag}" = "${tag%/>}" ] && depth=$((depth + 1))
+        tag="${tag#*<}" tag="${tag%%[ >]*}"
+        stack="${stack},${tag}"
         tag=''
         ;;
       *) :
         ;;
     esac
   done
-  printf '<span class="count">%i</span>' "$idoff"
+  printf '<span class="count">%i</span>' "$sl_num"
 }
 
 printf '</body></html>'
index 2f5ca873257156f7a560c2e1e5acf196996a23f2..423f923085b1f8c53243e0aa185ee0f909999ea4 100644 (file)
@@ -3,8 +3,8 @@
 footer,
 body a.toplevel:before,
 body span.count,
-div.slide:target:after,
-div.slide:target + a, div.slide:target + a + a,
+section.slide:target:after,
+section.slide:target + a, section.slide:target + a + a,
 :target + a:before, :target + a + a:before
 { color: #888; }
 
@@ -13,28 +13,28 @@ body
   background-image: repeating-linear-gradient( to bottom right, #AAA, #999 8px);
 }
 
-div.slide
+section.slide
 { background-color: #FFF;
   background-image: repeating-linear-gradient( #FFF, #EEE 4px);
 }
 
-div.slide:target:after,
+section.slide:target:after,
 footer:before, body:after
 { background-color: #EEE;
   background-image: repeating-linear-gradient(#EEE, #DDD 8px);
 }
 
-div.slide h1, div.slide h2
+section.slide h1, section.slide h2
 { background-color: #EEE;
   background-image: repeating-linear-gradient(#EEE, #DDD 8px);
 }
 
-div.slide pre, div.slide code
+section.slide pre, section.slide code
 { background-color: #DDD;
   background-image: repeating-linear-gradient(#CCC, #DDD 4px);
 }
 
-div.slide:after  /* slide number on overview screen */
+section.slide:after  /* slide number on overview screen */
 { color: #AAA; }
 
 /* === Overall Layout === */
@@ -129,11 +129,11 @@ body span.count {
 
 /* ==== Overview Screen ==== */
 
-div.slide, a.nextslide {
+section.slide, a.nextslide {
   font-size: .15625em;
 }
 
-div.slide {
+section.slide {
   position: relative;
   display: inline-block;
   overflow: hidden;
@@ -142,7 +142,7 @@ div.slide {
   border: 1px solid black;
 }
 
-div.slide:after {  /* slide number */
+section.slide:after {  /* slide number */
   position: absolute;
   bottom: 0; left: 0;
   font-size: 15em;
@@ -153,7 +153,7 @@ div.slide:after {  /* slide number */
   #color: #DDD;
 }
 
-div.slide + a { display: none; }
+section.slide + a { display: none; }
 a.nextslide {
   display: inline-block;
   position: relative;
@@ -162,30 +162,30 @@ a.nextslide {
   color: transparent;
   z-index: 2;
 }
-#div.slide:nth-of-type(1) { margin-right: .5em; }
+#section.slide:nth-of-type(1) { margin-right: .5em; }
 
 /* ==== Slide Appearance ==== */
 
-div.slide {
+section.slide {
   #background: #FFF no-repeat center;
   text-align: center;
   line-height: 1.5em;
 }
 
-div.slide > * {
+section.slide > * {
   margin-top: 1em;
   max-width: 85%;
   margin-left: auto;
   margin-right: auto;
 }
 
-div.slide > *:first-child:last-child,
-div.slide > h2:first-child + :last-child {
+section.slide > *:first-child:last-child,
+section.slide > h2:first-child + :last-child {
   margin-top: 20%;
   transform: translate(0, -50%);
 }
 
-div.slide h1, div.slide h2 {
+section.slide h1, section.slide h2 {
   display: block;
   text-align: center;
   font-size: 1.5em;
@@ -195,60 +195,60 @@ div.slide h1, div.slide h2 {
   #background: #EEE repeating-linear-gradient(#EEE, #DDD 8px);
 }
 
-div.slide h1,
-div.slide > h1:first-child:last-child {
+section.slide h1,
+section.slide > h1:first-child:last-child {
   margin-top: 25%;
   margin-bottom: 0;
   padding: .5em 2em;
 }
 
-div.slide h2 {
+section.slide h2 {
   padding: .25em 1em;
 }
 
-div.slide > table {
+section.slide > table {
   width: 85%;
 }
-div.slide * table {
+section.slide * table {
   width: 100%;
 }
 
-div.slide ul li {
+section.slide ul li {
   list-style-type: square;
   margin-left: 2em;
 }
 
-div.slide ul ul, div.slide ul ol,
-div.slide ol ul, div.slide ol ol {
+section.slide ul ul, section.slide ul ol,
+section.slide ol ul, section.slide ol ol {
   margin-left: -1em;
 }
 
-div.slide > ul,
-div.slide > ol {
+section.slide > ul,
+section.slide > ol {
   width: fit-content;
   margin: .25em auto;
 }
 
-div.slide li pre {
+section.slide li pre {
   margin-bottom: .25em;
 }
 
-div.slide pre, div.slide code {
+section.slide pre, section.slide code {
   #background-color: rgba(224,224,224,128);
   font-family: monospace;
 }
-div.slide pre {
+section.slide pre {
   padding: 1ex;
   text-align: left;
   overflow: hidden;
 }
-div.slide code {
+section.slide code {
   padding: 0 .5em;
 }
 
 /* ==== Slide Display ==== */
 
-div.slide:target {
+section.slide:target {
   position: fixed;
   z-index: 3;
   top: 0; bottom: 0; left: 0; right: 0;
@@ -259,7 +259,7 @@ div.slide:target {
 }
 
 /* slide number, footer bar*/
-div.slide:target:after {
+section.slide:target:after {
   position: absolute;
   bottom: 0; left: 0;
   width: 100%;
@@ -273,8 +273,8 @@ div.slide:target:after {
 }
 
 /* back and forth link buttons */
-div.slide:target + a,
-div.slide:target + a + a {
+section.slide:target + a,
+section.slide:target + a + a {
   position: static;
   display: block;
   font-size: inherit;