#! /bin/sh #description: format file according to https://wiki.ubuntu.com/Testing/TestCaseFormat #usage: test-case-format files INDENTATION="4" _usage() { printf "%s\\n" "Usage: ${PROGNAME} testcase ..." printf "%s\\n" "https://wiki.ubuntu.com/Testing/TestCaseFormat" } _die() { [ -z "${1}" ] || printf "%s\\n" "${*}" >&2 _usage >&2; exit 1 } _basename() { [ -z "${1}" ] && return 1 || _basename__name="${1}" [ -z "${2}" ] || _basename__suffix="${2}" case "${_basename__name}" in /*|*/*) _basename__name="$(expr "${_basename__name}" : '.*/\([^/]*\)')" ;; esac if [ -n "${_basename__suffix}" ] && [ "${#_basename__name}" -gt "${#2}" ]; then if [ X"$(printf "%s" "${_basename__name}" | cut -c"$((${#_basename__name} - ${#_basename__suffix} + 1))"-"${#_basename__name}")" \ = X"$(printf "%s" "${_basename__suffix}")" ]; then _basename__name="$(printf "%s" "${_basename__name}" | cut -c1-"$((${#_basename__name} - ${#_basename__suffix}))")" fi fi printf "%s\\n" "${_basename__name}" } _tmp_files() { mkdir -p /tmp/"${PROGNAME}"/indent #this file can also be copied to ~/.vim/indent/html.vim so #vim indent html files the testcase way
/
/
cat > /tmp/"${PROGNAME}"/indent/html.vim << EOF " Description: html indenter " Author: Johannes Zellner " Last Change: Mo, 05 Jun 2006 22:32:41 CEST " Restoring 'cpo' and 'ic' added by Bram 2006 May 5 " Globals: g:html_indent_tags -- indenting tags " g:html_indent_strict -- inhibit 'O O' elements " g:html_indent_strict_table -- inhibit 'O -' elements " Only load this indent file when no other was loaded. if exists("b:did_indent") finish endif let b:did_indent = 1 " [-- local settings (must come before aborting the script) --] setlocal indentexpr=HtmlIndentGet(v:lnum) setlocal indentkeys=o,O,*,<>>,{,} if exists('g:html_indent_tags') unlet g:html_indent_tags endif " [-- helper function to assemble tag list --] fun! HtmlIndentPush(tag) if exists('g:html_indent_tags') let g:html_indent_tags = g:html_indent_tags.'\|'.a:tag else let g:html_indent_tags = a:tag endif endfun " [-- --] call HtmlIndentPush('a') call HtmlIndentPush('abbr') call HtmlIndentPush('acronym') call HtmlIndentPush('address') call HtmlIndentPush('b') call HtmlIndentPush('bdo') call HtmlIndentPush('big') call HtmlIndentPush('blockquote') call HtmlIndentPush('button') call HtmlIndentPush('caption') call HtmlIndentPush('center') call HtmlIndentPush('cite') call HtmlIndentPush('code') call HtmlIndentPush('colgroup') call HtmlIndentPush('dd') call HtmlIndentPush('del') call HtmlIndentPush('dfn') call HtmlIndentPush('dir') call HtmlIndentPush('div') call HtmlIndentPush('dl') call HtmlIndentPush('dt') call HtmlIndentPush('em') call HtmlIndentPush('fieldset') call HtmlIndentPush('font') call HtmlIndentPush('form') call HtmlIndentPush('frameset') call HtmlIndentPush('h1') call HtmlIndentPush('h2') call HtmlIndentPush('h3') call HtmlIndentPush('h4') call HtmlIndentPush('h5') call HtmlIndentPush('h6') call HtmlIndentPush('i') call HtmlIndentPush('iframe') call HtmlIndentPush('ins') call HtmlIndentPush('kbd') call HtmlIndentPush('label') call HtmlIndentPush('legend') call HtmlIndentPush('map') call HtmlIndentPush('menu') call HtmlIndentPush('noframes') call HtmlIndentPush('noscript') call HtmlIndentPush('object') call HtmlIndentPush('ol') call HtmlIndentPush('optgroup') " call HtmlIndentPush('pre') call HtmlIndentPush('q') call HtmlIndentPush('s') call HtmlIndentPush('samp') call HtmlIndentPush('script') call HtmlIndentPush('select') call HtmlIndentPush('small') call HtmlIndentPush('span') call HtmlIndentPush('strong') call HtmlIndentPush('style') call HtmlIndentPush('sub') call HtmlIndentPush('sup') call HtmlIndentPush('table') call HtmlIndentPush('textarea') call HtmlIndentPush('title') call HtmlIndentPush('tt') call HtmlIndentPush('u') call HtmlIndentPush('ul') call HtmlIndentPush('var') " [-- --] if !exists('g:html_indent_strict') call HtmlIndentPush('body') call HtmlIndentPush('head') call HtmlIndentPush('html') call HtmlIndentPush('tbody') endif " [-- --] if !exists('g:html_indent_strict_table') call HtmlIndentPush('th') call HtmlIndentPush('td') call HtmlIndentPush('tr') call HtmlIndentPush('tfoot') call HtmlIndentPush('thead') endif delfun HtmlIndentPush let s:cpo_save = &cpo set cpo-=C " [-- count indent-increasing tags of line a:lnum --] fun! HtmlIndentOpen(lnum, pattern) let s = substitute('x'.getline(a:lnum), \ '.\{-}\(\(<\)\('.a:pattern.'\)\>\)', "\1", 'g') let s = substitute(s, "[^\1].*$", '', '') return strlen(s) endfun " [-- count indent-decreasing tags of line a:lnum --] fun! HtmlIndentClose(lnum, pattern) let s = substitute('x'.getline(a:lnum), \ '.\{-}\(\(<\)/\('.a:pattern.'\)\>>\)', "\1", 'g') let s = substitute(s, "[^\1].*$", '', '') return strlen(s) endfun " [-- count indent-increasing '{' of (java|css) line a:lnum --] fun! HtmlIndentOpenAlt(lnum) return strlen(substitute(getline(a:lnum), '[^{]\+', '', 'g')) endfun " [-- count indent-decreasing '}' of (java|css) line a:lnum --] fun! HtmlIndentCloseAlt(lnum) return strlen(substitute(getline(a:lnum), '[^}]\+', '', 'g')) endfun " [-- return the sum of indents respecting the syntax of a:lnum --] fun! HtmlIndentSum(lnum, style) if a:style == match(getline(a:lnum), '^\s*') let open = HtmlIndentOpen(a:lnum, g:html_indent_tags) let close = HtmlIndentClose(a:lnum, g:html_indent_tags) if 0 != open || 0 != close return open - close endif endif endif if '' != &syntax && \ synIDattr(synID(a:lnum, 1, 1), 'name') =~ '\(css\|java\).*' && \ synIDattr(synID(a:lnum, strlen(getline(a:lnum)), 1), 'name') \ =~ '\(css\|java\).*' if a:style == match(getline(a:lnum), '^\s*}') return HtmlIndentOpenAlt(a:lnum) - HtmlIndentCloseAlt(a:lnum) endif endif return 0 endfun fun! HtmlIndentGet(lnum) " Find a non-empty line above the current line. let lnum = prevnonblank(a:lnum - 1) " Hit the start of the file, use zero indent. if lnum == 0 return 0 endif " [-- special handling for
--] if getline(a:lnum-1) =~ '\c' if getline(a:lnum) =~ '\c
' return indent(lnum) + (&sw) endif endif " [-- special handling for
/
: --] if getline(a:lnum-1) =~ '\c' if getline(a:lnum) =~ '\c' return indent(lnum) endif if getline(a:lnum) =~ '\c
' return indent(lnum) - (&sw) endif return -1 endif let restore_ic = &ic setlocal ic " ignore case " [-- special handling for
: no indenting --]
    if getline(a:lnum) =~ '\c
' \ || 0 < searchpair('\c
', '', '\c
', 'nWb') \ || 0 < searchpair('\c
', '', '\c
', 'nW') " we're in a line with or inside
 ... 
if restore_ic == 0 setlocal noic endif return -1 endif " [-- special handling for : use cindent --] let js = ', 05 Jun 2006 " ZDR: This needs to be an AND (we are 'after the start of the pair' AND " we are 'before the end of the pair'). Otherwise, indentation " before the start of the script block will be affected; the end of " the pair will still match if we are before the beginning of the " pair. " if 0 < searchpair(js, '', '', 'nWb') \ && 0 < searchpair(js, '', '', 'nW') " we're inside javascript if getline(lnum) !~ js && getline(a:lnum) != '' if restore_ic == 0 setlocal noic endif return cindent(a:lnum) endif endif if getline(lnum) =~ '\c' " line before the current line a:lnum contains " a closing . --> search for line before " starting
 to restore the indent.
	let preline = prevnonblank(search('\c
', 'bW') - 1)
	if preline > 0
	    if restore_ic == 0
	      setlocal noic
	    endif
	    return indent(preline)
	endif
    endif

    let ind = HtmlIndentSum(lnum, -1)
    let ind = ind + HtmlIndentSum(a:lnum, 0)

    if restore_ic == 0
	setlocal noic
    endif

    return indent(lnum) + (&sw * ind)
endfun

let &cpo = s:cpo_save
unlet s:cpo_save

" [-- EOF /indent/html.vim --]
EOF

    cat > /tmp/"${PROGNAME}"/vimrc << EOF
set runtimepath=/tmp/${PROGNAME},\$VIMRUNTIME
syntax on
set ffs=unix,dos
set encoding=utf-8          "utf is able to represent any character
set softtabstop=${INDENTATION}
set shiftwidth=${INDENTATION}
set expandtab               "tabs mutate into spaces, if you wanna insert "real"
filetype plugin indent on   "enable filetype-specific plugins
EOF
}

_format() {
    for _format__testcase; do
        printf "%s\\n" "${_format__testcase}"
        tidy -f /tmp/"${PROGNAME}"/testcase -xml \
            -i "${_format__testcase}" > /dev/null
        [ "${?}" -eq "2" ] && { cat /tmp/"${PROGNAME}"/testcase; exit 1; }
        vim -es -u /tmp/"${PROGNAME}"/vimrc \
            -c "set ft=html" -c "normal gg=G" -c wq "${_format__testcase}"
    done
}

PROGNAME="$(_basename "${0}")"

if [ ! -t 0 ]; then
    #there is input comming from pipe or file, add to the end of $@
    set -- "${@}" $(cat)
fi

[ "${#}" -eq "0" ] && _die

for arg in "${@}"; do #parse options
    case "${arg}" in
        -h|--help) _usage && exit ;;
        -*) _die "$(expr "${0}" : '.*/\([^/]*\)'): unrecognized option '${arg}'" ;;
    esac
done

[ -f "$(command -v "vim")" ]  || { printf "%b\\n" \
    "${PROGNAME}: install 'vim' & 'tidy' to run this program\n$ sudo apt-get install vim tidy" >&2
    exit 1; }
[ -f "$(command -v "tidy")" ] || { printf "%b\\n" \
    "${PROGNAME}: install 'tidy' to run this program\n$ sudo apt-get install tidy" >&2
    exit 1; }

_tmp_files
_format "${@}"