s4

changeset 942:5d70fa029f8d

Support MathJax rendering
author HIROSE Yuuji <yuuji@gentei.org>
date Mon, 25 Oct 2021 18:39:44 +0900
parents 79c7e64884c4
children b8d09525a0b4
files examples/sns/form/blog.def s4-blog.sh s4-cgi.sh s4-funcs.sh
diffstat 4 files changed, 61 insertions(+), 45 deletions(-) [+]
line diff
     1.1 --- a/examples/sns/form/blog.def	Wed Sep 22 08:39:36 2021 +0900
     1.2 +++ b/examples/sns/form/blog.def	Mon Oct 25 18:39:44 2021 +0900
     1.3 @@ -3,6 +3,7 @@
     1.4  タイトル:title:s:text:maxlength="200"
     1.5  コメント書込通知:notify:s:select:しない=no 管理者のみに通知(グループの場合のみ)=admin 所有者全員に通知=all
     1.6  稼動状態:state:s:select:稼動=active 凍結(新規書込停止)=frozen
     1.7 +数式使用(MathJax):mathjax:s:checkbox:記事中 \(数式\) または \[数式\] を使う場合はチェック=yes
     1.8  所有者:owner:s:owner:
     1.9  筆者:author:s:author:
    1.10  時刻:ctime:s:stamp:
     2.1 --- a/s4-blog.sh	Wed Sep 22 08:39:36 2021 +0900
     2.2 +++ b/s4-blog.sh	Mon Oct 25 18:39:44 2021 +0900
     2.3 @@ -183,6 +183,7 @@
     2.4    blog_notify=`getvalbyid blog notify "$rowid"`
     2.5    blog_team=`blog_getteam "$rowid"`
     2.6    blog_mode=`getvalbyid blog mode "$rowid"`
     2.7 +  blog_math=`getvalbyid blog mathjax "$rowid"`
     2.8    case "$blog_notify" in # "all", "admin" or "no" (or NULL)
     2.9      admin)	notifyto=adm ;;
    2.10      *)		notifyto="" ;;
    2.11 @@ -269,7 +270,7 @@
    2.12  	;;
    2.13      esac
    2.14    fi
    2.15 -  href4="<a href=\"#bottom\" accesskey=\"b\" title=\"Shortcut: B${nl}to the Bottom\"> 末尾へ</a>"
    2.16 +  href4="${blog_math:+Math} <a href=\"#bottom\" accesskey=\"b\" title=\"Shortcut: B${nl}to the Bottom\"> 末尾へ</a>"
    2.17    $isgrpadmin &&
    2.18        href5="<a href=\"?blogseen+$rowid\" accesskey=\"s\" title=\"Shortcut: S${nl}State of Accesses\"> 読刻</a>"
    2.19    quizmodefile=$tmpd/quiz; rm -f "$quizmodefile"	# XXX: Global state
    2.20 @@ -416,6 +417,7 @@
    2.21      echo "時間をおいてください(Visit later please)." | html p
    2.22      return
    2.23    fi
    2.24 +  echo "${blog_math:+$mathjax}"
    2.25    echo '<table class="blog_replies"> <!-- blog:blog_showentry() main table -->'
    2.26    # If, nLimit = 50
    2.27    # show article:1, hide(2, 3), show(4, ...)
    2.28 @@ -447,7 +449,7 @@
    2.29    err "blog_showentry  Started: `gdate +%S.%03N` ${fetch_ajax:+ajax}"
    2.30    # Start blog_replies table
    2.31    $CAT $midfile |
    2.32 -  while IFS='|' read id edit notify uid author uname icon aid \
    2.33 +  while IFS='|' read -r id edit notify uid author uname icon aid \
    2.34  	   tm reki new hte fa imgids
    2.35    do
    2.36      if [ -n "$omitline" ]; then
    2.37 @@ -661,7 +663,7 @@
    2.38    owner=`getvalbyid blog owner $1`
    2.39    title=`getvalbyid blog title $1`
    2.40    ge=`gecos "$owner"`
    2.41 -  htmlowner=`echo ${ge:-$owner}|htmlescape`
    2.42 +  htmlowner=`printf '%s' "${ge:-$owner}"|htmlescape`
    2.43    fh=$tmpd/formhead
    2.44    echo "$time [$title]@$htmlowner" > $fh
    2.45    lshandoutsub "$owner" "$@" \
    2.46 @@ -670,7 +672,7 @@
    2.47  	   -D_FORMHEAD_="syscmd(cat $fh)" \
    2.48  	   -D_FORM_="syscmd(cat)" -D_DUMPHEAD_= -D_DUMPTABLE_= \
    2.49  	   $layout/html.m4.html $layout/form+dump-whead.m4.html
    2.50 -  gn=`echo $owner|htmlescape`
    2.51 +  gn=`printf '%s' "$owner"|htmlescape`
    2.52    echo "<p><a href=\"?lshandoutall+$1\">グループ $gn すべてのレポート板集計</a></p>"
    2.53  }
    2.54  gethandoutcsv() {
    2.55 @@ -756,7 +758,7 @@
    2.56      _m4 -D_TITLE_="提出状況" $layout/html.m4.html
    2.57      ge=`gecos "$owner"`
    2.58      tbls=""
    2.59 -    grptxt=`echo "${ge:-$owner}"|htmlescape`
    2.60 +    grptxt=`printf '%s' "${ge:-$owner}"|htmlescape`
    2.61      echo "<h1>$grptxt 書き込み状況一覧</h1>"
    2.62    fi
    2.63    if [ -z "$SQL" ]; then
    2.64 @@ -766,7 +768,7 @@
    2.65        [ $brid = 0 ] && continue
    2.66        time=`getvalbyid blog ctime $brid|colrm 11`
    2.67        title=`getvalbyid blog title $brid`
    2.68 -      titleH=`echo "$title"|htmlescape`
    2.69 +      titleH=`printf '%s' "$title"|htmlescape`
    2.70        state=`getvalbyid blog state $brid|htmlescape`
    2.71        tt="handout_$brid"
    2.72        [ "$state" = "frozen" ] && frozen=" $FROZEN_TAG" || frozen=""
    2.73 @@ -1053,7 +1055,7 @@
    2.74      cat <<-EOF
    2.75  	<tr>
    2.76  	 <td><a href="?home+$uid">`echo "$hexge"|unhexize|htmlescape`</a></td>
    2.77 -	 <td>`echo ${u%%@*}|htmlescape`</td>
    2.78 +	 <td>`printf '%s' "${u%%@*}"|htmlescape`</td>
    2.79  	 $td${time:----}</td></tr>
    2.80  	EOF
    2.81    done
    2.82 @@ -1180,7 +1182,7 @@
    2.83      rowid=$((${kwd#\#} + 0))	# Force to be a number
    2.84      kc="ar.rowid = $rowid"
    2.85    else
    2.86 -    for k in `echo "$kwd" | sed "s/'/''/g"`; do		# With wrap quotes
    2.87 +    for k in `printf '%s' "$kwd" | sed "s/'/''/g"`; do	# With wrap quotes
    2.88        ctime=""
    2.89        if expr x"$k" : 'x@[><= ]*[1-9][][0-9]*-[][0-9:-]*$' >/dev/null >&2; then
    2.90  	# '@<2016-10-10'	-> ctime < '2016-10-10'
    2.91 @@ -1218,14 +1220,14 @@
    2.92  	e=""
    2.93  	case "$k" in
    2.94  	  *${likeesc}*) e="" ;;		# Giving up char-escaping
    2.95 -	  *%*|*_*) k=`echo "$k"|sed "s/\([%_]\)/${likeesc}\1/g"`
    2.96 +	  *%*|*_*) k=`printf '%s' "$k"|sed "s/\([%_]\)/${likeesc}\1/g"`
    2.97  	       e=" ESCAPE '$likeesc'" ;;
    2.98  	esac
    2.99  	kc=$kc${kc:+" AND "}"content LIKE '%$k%'$e"
   2.100        fi
   2.101      done
   2.102    fi
   2.103 -  kwd=`echo "$kwd"|htmlescape`
   2.104 +  kwd=`printf '%s' "$kwd"|htmlescape`
   2.105    owner=`getpar owner`
   2.106    owner=${owner:-$1}
   2.107    grid=`getpar grid`
   2.108 @@ -1359,11 +1361,11 @@
   2.109    newval=`getvalbyid blog "$2" "$1"`
   2.110    alert="${msg:+, \"alert\": \"$msg\"}"
   2.111    json=$(cat <<-EOF
   2.112 -	{"code": $code, "$2": "`echo "$newval"|sed 's/"/\\\\"/g'`"$alert}
   2.113 +	{"code": $code, "$2": "`printf '%s' "$newval"|sed 's/"/\\\\"/g'`"$alert}
   2.114  	EOF
   2.115        )
   2.116    err blog_setval: returning JSON: "$json"
   2.117 -  echo "$json"
   2.118 +  printf '%s\n' "$json"
   2.119    exit
   2.120  }
   2.121  
   2.122 @@ -1387,7 +1389,7 @@
   2.123    else
   2.124      owner=`getpar owner`
   2.125    fi
   2.126 -  htmlowner=`echo $owner|htmlescape`
   2.127 +  htmlowner=`printf '%s' $owner|htmlescape`
   2.128    err blog-add: \$1=$grprowid rowid=$rowid owner=$owner
   2.129    if isgroup "$owner"; then
   2.130      if [ -z "$grprowid" ]; then
   2.131 @@ -1481,7 +1483,7 @@
   2.132    fi
   2.133    title=`getvalbyid blog title $rowid`
   2.134    owner=`getvalbyid blog owner $rowid`
   2.135 -  htmlowner=`echo $owner|htmlescape`
   2.136 +  htmlowner=`printf '%s' $owner|htmlescape`
   2.137    qowner=`sqlquotestr "$owner"`
   2.138    if [ -z "$title" ]; then
   2.139      echo "日記番号指定が無効です。" | html p
     3.1 --- a/s4-cgi.sh	Wed Sep 22 08:39:36 2021 +0900
     3.2 +++ b/s4-cgi.sh	Mon Oct 25 18:39:44 2021 +0900
     3.3 @@ -44,11 +44,11 @@
     3.4  EOF
     3.5  }
     3.6  cgi_text() {
     3.7 -  _v=`echo "$2"|htmlescape`
     3.8 +  _v=`printf '%s' "$2"|htmlescape`
     3.9    echo "<input type=\"text\" name=\"$1\" value=\"$_v\" $3>"
    3.10  }
    3.11  cgi_textarea() {
    3.12 -  _v=`echo "$2"|htmlescape`
    3.13 +  _v=`printf '%s' "$2"|htmlescape`
    3.14    cat<<EOF
    3.15  <textarea name="$1" $3>$_v</textarea>
    3.16  EOF
    3.17 @@ -79,7 +79,7 @@
    3.18    # $1=name $2=dir $3=func $4=args...
    3.19    # `dir' should contain $name.count and $name.N where N is 1 upto N
    3.20    i=1 name=$1 dir=$2 func=$3
    3.21 -  argnomulti=`echo "$4"|sed 's/multiple//'` # No multiple for Replaced entres
    3.22 +  argnomulti=`printf '%s' "$4"|sed 's/multiple//'` # No multiple for Replaced entries
    3.23    n=`cat $dir/$name.count`
    3.24    case "$func" in
    3.25      *file) addrename=yes ;;
     4.1 --- a/s4-funcs.sh	Wed Sep 22 08:39:36 2021 +0900
     4.2 +++ b/s4-funcs.sh	Mon Oct 25 18:39:44 2021 +0900
     4.3 @@ -78,6 +78,8 @@
     4.4  whatsnewdays=${WHATS_NEW_DAYS:-14}
     4.5  main_session=`date +%F-$$`
     4.6  session=$main_session
     4.7 +mathjax=${MATHJAX:-'<script>MathJax = {tex: {tags: "ams"}};</script>
     4.8 +<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script><script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>'}
     4.9  
    4.10  tconfs=""
    4.11  imgcached=cache/${S4WORLD:+$S4WORLD/}img.`date +%Y/%m`
    4.12 @@ -92,7 +94,11 @@
    4.13  logtag="($$)${S4WORLD:+{$S4WORLD\}}"
    4.14  exec 3>> $logdir/debug.out
    4.15  err() {
    4.16 -  echo "[`date +%F-%T%z`]$logtag $@" 1>&3
    4.17 +  # echo "[`date +%F-%T%z`]$logtag $@" 1>&3
    4.18 +  # Avoid backslash escape sequences
    4.19 +  cat<<EOF 1>&3
    4.20 +[`date +%F-%T%z`]$logtag $@
    4.21 +EOF
    4.22  }
    4.23  case "$HTTP_USER_AGENT" in
    4.24    *i[Pp]hone*|*[Aa]ndroid*)	touchpanel=1 ;;
    4.25 @@ -454,8 +460,8 @@
    4.26    if [ -z "$1" ]; then
    4.27      tee -a $querylog
    4.28    else
    4.29 -    echo "$@" >> $querylog
    4.30 -    echo "$@"
    4.31 +    printf '%s\n' "$@" >> $querylog
    4.32 +    printf '%s\n' "$@"
    4.33    fi  >&5
    4.34    echo ".output stdout" >&5
    4.35    cat $sqo
    4.36 @@ -801,11 +807,11 @@
    4.37        if [ x"$user" = x"$val" ]; then
    4.38  	echo $user; return
    4.39        elif ismember $user $val; then
    4.40 -	echo $val; return
    4.41 +	printf '%s' "$val"; return
    4.42        fi ;;
    4.43    esac
    4.44  ## err getpar/ret: "val=[$val]"
    4.45 -  echo "$val"
    4.46 +  printf '%s' "$val"
    4.47  }
    4.48  setskey() {
    4.49    # For quick response...(?)
    4.50 @@ -845,25 +851,25 @@
    4.51       "X'"*)			# quoted hex string
    4.52         echo $1 ;;
    4.53       *\"*)			# string including dbl-quote"
    4.54 -       v=`echo "$v"|sed -e 's/\"/\"\"/g'`
    4.55 -       echo "\"$v\""
    4.56 +       v=`printf '%s' "$v"|sed -e 's/\"/\"\"/g'`
    4.57 +       printf '%s' "\"$v\""
    4.58         return ;;
    4.59       *.*.*|*-*-*|*[Ee]*[Ee]*|[Ee]*|*[\ -,:-df-~]*) # string
    4.60 -       echo "\"$v\""
    4.61 +       printf '%s' "\"$v\""
    4.62         return ;;
    4.63       *)
    4.64         if expr "$v" : '[-0-9.Ee][-0-9.Ee]*$' >/dev/null 2>&1; then
    4.65 -	 echo $v		# MAYBE numeric, maybe...
    4.66 +	 printf '%s' $v		# MAYBE numeric, maybe...
    4.67         else
    4.68 -	 echo "\"$v\""
    4.69 +	 printf '%s' "\"$v\""
    4.70         fi ;;
    4.71     esac)
    4.72  }
    4.73  sqlquotestr() (
    4.74    case "$1" in
    4.75 -    *\'*)	v=`echo "$1"| sed "s/'/''/g"`
    4.76 -		echo "'$v'" ;;
    4.77 -    *)		echo "'$1'" ;;
    4.78 +    *\'*)	v=`printf '%s' "$1"| sed "s/'/''/g"`
    4.79 +		printf '%s' "'$v'" ;;
    4.80 +    *)		printf '%s' "'$1'" ;;
    4.81    esac
    4.82  )
    4.83  mktempd() {
    4.84 @@ -1002,7 +1008,7 @@
    4.85  	   rm -f $td/$c.count
    4.86  	   case $type in
    4.87  	     file:*)
    4.88 -	       echo "$val" \
    4.89 +	       printf '%s\n' "$val" \
    4.90  		   | while read fn; do
    4.91  		       file=$td/$fn
    4.92  		       if [ ! -s "$file" ]; then
    4.93 @@ -1021,7 +1027,7 @@
    4.94  	       ;;
    4.95  	   esac
    4.96  	 fi
    4.97 -	 echo "$val"		# Keep newlines by ""
    4.98 +	 printf '%s' "$val"
    4.99  	 return
   4.100         fi
   4.101       done
   4.102 @@ -1565,7 +1571,6 @@
   4.103  	#echo u=$us
   4.104  	#v="`echo ${us#*=}|nkf -Ww -mQ|sed -e 's/\"/\"\"/g'`"
   4.105  	v="`echo ${us#*=}|unhexize|sed -e 's/\"/\"\"/g'`"
   4.106 - # err k=$k v=$v
   4.107  	case "$k" in
   4.108  	  *:filename)
   4.109  	    mimetype=`file --mime-type - < "$tmpd/$v"|cut -d' ' -f2`
   4.110 @@ -4218,9 +4223,9 @@
   4.111  	  # Binary update line is TOO LONG to pipelining
   4.112  	  sqlfile="$tmpd/sqlf.$$"
   4.113  	  if [ -n "$transaction" ]; then
   4.114 -	    echo "$sql" >> $transaction
   4.115 +	    printf '%s' "$sql" >> $transaction
   4.116  	  else
   4.117 -	    echo "$sql" > $sqlfile
   4.118 +	    printf '%s' "$sql" > $sqlfile
   4.119  	    query ".read $sqlfile"
   4.120  	  fi
   4.121  	fi
   4.122 @@ -4235,7 +4240,8 @@
   4.123  	limit="limit 1 offset $i"
   4.124  	i=$((i+1))		# increase beforehand against continue
   4.125  	val=`getvalquote $tbl $col "$limit"`
   4.126 -	[ -z "$val" -o x"$val" = x'""' -o x"$val" = x"NULL" ] && continue
   4.127 +	##XXX [ -z "$val" -o x"$val" = x'""' -o x"$val" = x"NULL" ] && continue
   4.128 +	[ -z "$val" -o x"$val" = x'""' ] && continue
   4.129  	## err $col=$val
   4.130  	bin=NULL
   4.131  	## err partype$col=`getpartype $col "$limit"`
   4.132 @@ -4251,6 +4257,9 @@
   4.133  	  *)    type=\"string\" ;;
   4.134  	esac
   4.135  	case `gettbl_coltype $tbl/$col` in
   4.136 +	  [Cc][Hh][Ee][Cc][Kk][Bb][Oo][Xx]|[Tt][Ee][Xx][Tt])
   4.137 +	    test x"$val" = x"NULL" && val="''"
   4.138 +	    ;;
   4.139  	  password)		# special care for password
   4.140  	    # name={password,pswd1,pswd2}
   4.141  	    p1=`getpar pswd1 "$limit"`
   4.142 @@ -4284,7 +4293,7 @@
   4.143  	if [ x"$bin" = x"NULL" ]; then
   4.144  	  ## err Normal-query: `echo $sql`
   4.145  	  if [ -n "$transaction" ]; then
   4.146 -	    echo "$sql" >> $transaction
   4.147 +	    printf '%s' "$sql" >> $transaction
   4.148  	  else
   4.149  	    query "$sql"
   4.150  	  fi
   4.151 @@ -4292,9 +4301,9 @@
   4.152  	  sqlfile="$tmpd/query.$$"
   4.153  	  ## err sqlfile=`ls -lF $sqlfile`
   4.154  	  if [ -n "$transaction" ]; then
   4.155 -	    echo "$sql" >> $transaction
   4.156 +	    printf '%s' "$sql" >> $transaction
   4.157  	  else
   4.158 -	    echo "$sql" > $sqlfile
   4.159 +	    printf '%s' "$sql" > $sqlfile
   4.160  	    query ".read $sqlfile"
   4.161  	  fi
   4.162  	fi
   4.163 @@ -4347,14 +4356,14 @@
   4.164    # Image Cache dir
   4.165    ## err genform: getcache=$2/$rowid
   4.166    td=`getcachedir "$2/$rowid"`
   4.167 -  while IFS=: read prompt name keytype type args; do
   4.168 +  while IFS=: read -r prompt name keytype type args; do
   4.169      [ -z "${prompt%%\#*}" ] && continue # skip comment line(#)
   4.170      sp="${args:+ }"
   4.171      form="" val=""
   4.172      if [ -n "$rowid" ]; then
   4.173        # err genform2a: Seeking for "$2.$name, type=$type"
   4.174        rawval=`getvalbyid $2 $name $rowid $td`
   4.175 -      val=`echo "$rawval"|htmlescape`
   4.176 +      val=`printf '%s\n' "$rawval"|htmlescape`
   4.177  ## err genform3a: getvalbyid $2 $name $rowid $td
   4.178  ## err genform3b: val="[$val]" type="$type"
   4.179      fi
   4.180 @@ -4366,7 +4375,7 @@
   4.181  	cgiform=cgi_multi_$type
   4.182  	if [ -s $td/$name.count -a -n "$val" ]; then
   4.183  	  form=`$cgiform $name $td`
   4.184 -	  val=$(echo "$val"|
   4.185 +	  val=$(printf '%s\n' "$val"|
   4.186  		     while read fn; do
   4.187  		       echo "<tr><td>`cat $td/$fn|htmlescape|hreflink`
   4.188  			</td></tr>$nl"
   4.189 @@ -4374,6 +4383,7 @@
   4.190  	  val="<table>$nl$val$nl</table>"
   4.191  	else
   4.192  	  #form="<input name=\"$name\" value=\"$val\" type=\"$type\"$sp$args>$nl"
   4.193 +
   4.194  	  form=`cgi_$type $name "$rawval" "$args"`
   4.195  	fi
   4.196  	;;
   4.197 @@ -4383,7 +4393,8 @@
   4.198  \"s,\([^ =][^=]*\)=\([^= ][^= ]*\),$fh value=\\"\2\\">\1</label>,g\"`"
   4.199  	;;
   4.200        [Cc][Hh][Ee][Cc][Kk][Bb][Oo][Xx])
   4.201 -	form="<label><input type=\"checkbox\" name=\"$name\" value=\"${args#*=}\">${args%=*}</label>"
   4.202 +	checked=${val:+ checked}
   4.203 +	form="<label><input type=\"checkbox\" name=\"$name\" value=\"${args#*=}\"$checked>${args%=*}</label>"
   4.204  	;;
   4.205        [Ss][Ee][Ll][Ee][Cc][Tt])
   4.206  	fh="<select name=\"$name\">$nl"
   4.207 @@ -4484,9 +4495,11 @@
   4.208      fi
   4.209    done < $1
   4.210    # enctype="multipart/form-data"
   4.211 +  cat<<-EOF
   4.212 +<form action="${GF_ACTION:-$myname}" method="POST" enctype="multipart/form-data">
   4.213 +	EOF
   4.214 +  test -n "$rowid" && printf '%s\n' "$rm" # Workaround for utf8 buggy NetBSD sh
   4.215    cat<<EOF
   4.216 -<form action="${GF_ACTION:-$myname}" method="POST" enctype="multipart/form-data">
   4.217 -${rowid:+$rm}
   4.218   <table class="b $2">
   4.219  $forms
   4.220   </table>$hiddens