diff --git a/analyze.sh b/analyze.sh index b741bcb734fa4a7275945215c208f43c5b78c5bb..73a2f495a5491ceb336fa24355b8e2dca10d6312 100755 --- a/analyze.sh +++ b/analyze.sh @@ -6,8 +6,11 @@ # Requirements: ImageMagick's identify and convert # -# TODO: Move this outside of the script -ASSUME_GREY=true +# If true, input files are assumed to be greyscale. +# If false, they are converted to greyscale before extracting statistics. +if [ "." == ".$ASSUME_GREY" ]; then + ASSUME_GREY=true +fi # TODO: Accept destination for identify-file as input diff --git a/presentation.sh b/presentation.sh index fe2a2d1f14a6d4e6091655bc6a07ebdf5b3f9c4a..01c2176c8f826f884a1edd00f343f5cb904dd2c1 100755 --- a/presentation.sh +++ b/presentation.sh @@ -59,5 +59,6 @@ if [ "." == ".$DESTINATION" ]; then exit 2 fi + get_commands "$SOURCE" gm convert "$SOURCE" $COMMANDS "$DESTINATION" diff --git a/quack.sh b/quack.sh index e809a4c7378e59584f4e5b7d4891fb65d5e55e1a..fa4060ca34dd9072ac798080aa95a9617012bf9e 100755 --- a/quack.sh +++ b/quack.sh @@ -126,6 +126,9 @@ TILE="false" # The view represents an end-user version of the scan. This will often be # downscaled, levelled, sharpened and JPEG'ed. export PRESENTATION="true" +# The image format for the presentation image. Possible values are png and jpg. +# jpg is recommended as this would normally be the choice for end-user presentation. +export PRESENTATION_IMAGE_DISP_EXT="jpg" # Overlay colors for indicating burned out high- and low-lights export OVERLAY_BLACK=3399FF @@ -133,13 +136,28 @@ export OVERLAY_WHITE=FFFF00 # Snippets are inserted verbatim at the top of the folder and the image pages. # Use them for specifying things like delivery date or provider notes. +# Note that these snippet can be overridden on a per-folder and per-image basis +# by creating special files in the source tree (see SPECIFIC_FOLDER_SNIPPET and +# SPECIFIC_IMAGE_SNIPPET_EXTENSION below). export SNIPPET_FOLDER="" export SNIPPET_IMAGE="" # End default settings. User-supplied overrides will be loaded from quack.settings +# If present in a source-folder, the content of the folder will be inserted into +# the generated folder HTML file. +SPECIFIC_FOLDER_SNIPPET="folder.snippet" +# If a file with image basename + this extension is encountered, the content will +# be inserted into the generated image HTML file. +SPECIFIC_IMAGE_SNIPPET_EXTENSION=".snippet" + +# If no OpenSeadragon is present, the scripts attempts to download this version. +OSD_ZIP="openseadragon-bin-1.0.0.zip" +OSD_DIRECT="http://github.com/openseadragon/openseadragon/releases/download/v1.0.0/$OSD_ZIP" + +START_PATH=`pwd` pushd `dirname $0` > /dev/null ROOT=`pwd` if [ -e "quack.settings" ]; then @@ -151,25 +169,29 @@ source "analyze.sh" popd > /dev/null # Local settings overrides general settings -if [ -e "quack.settings" ]; then - echo "Sourcing user settings from quack.settings in `pwd`" - source "quack.settings" +if [ ! "$START_PATH" == "$ROOT" ]; then + if [ -e "quack.settings" ]; then + echo "Sourcing user settings from quack.settings in `pwd`" + source "quack.settings" + fi fi - - if [ ".true" == ".$FORCE_BLOWN" ]; then # When we force regeneration of blown, we myst also regenerate the blown thumbs. export FORCE_BLOWN_THUMBS=true fi PRESENTATION_SCRIPT="$ROOT/presentation.sh" -FOLDER_TEMPLATE="$ROOT/folder_template.html" -IMAGE_TEMPLATE="$ROOT/image_template.html" +if [ -f "$START_PATH/presentation.sh" ]; then + echo "Using presentation.sh located in $START_PATH" + PRESENTATION_SCRIPT="$START_PATH/presentation.sh" +fi +FOLDER_TEMPLATE="$ROOT/web/folder_template.html" +IMAGE_TEMPLATE="$ROOT/web/image_template.html" DRAGON="openseadragon.min.js" function usage() { - echo "quack 1.1 beta - Quality Assurance oriented ALTO viewer" + echo "quack 1.2 beta - Quality Assurance oriented ALTO viewer" echo "" echo "Usage: ./quack.sh source destination" echo "" @@ -197,10 +219,37 @@ if [ "." == ".$DEST" ]; then usage exit 2 fi -if [ ! -f "$ROOT/$DRAGON" ]; then - echo "The file $ROOT/$DRAGON does not exist" >&2 - echo "Please download it at http://openseadragon.github.io/#download" >&2 - exit +if [ ! -f "$ROOT/web/$DRAGON" ]; then + if [ -f "$ROOT/$DRAGON" ]; then + echo "Copying $DRAGON from Quack root to the web folder" + cp "$ROOT/$DRAGON" "$ROOT/web/" + else + echo "The file $ROOT/$DRAGON or $ROOT/web/$DRAGON does not exist" >&2 + if [ "." == ".`which wget`" -o "." == ".`which unzip`" ]; then + echo "Please download it at http://openseadragon.github.io/#download" >&2 + echo "Tested version is 1.0.0, which can be downloaded from" >&2 + echo "$OSD_DIRECT" >&2 + exit + else + echo "Attempting to download of OpenSeadragon from" >&2 + echo "$OSD_DIRECT" + wget "$OSD_DIRECT" -O "$ROOT/web/$OSD_ZIP" + pushd "$ROOT/web" > /dev/null + unzip "$ROOT/web/$OSD_ZIP" "openseadragon-bin-1.0.0/openseadragon.min.js" + mv "openseadragon-bin-1.0.0/openseadragon.min.js" "$DRAGON" + rm -r "openseadragon-bin-1.0.0" + popd > /dev/null + rm "$ROOT/web/$OSD_ZIP" + if [ ! -f "$ROOT/web/$DRAGON" ]; then + echo "Automatic OpenSeadragon download and installation failed." >&2 + echo "Please download it at http://openseadragon.github.io/#download" >&2 + echo "Tested version is 1.0.0, which can be downloaded from" >&2 + echo "$OSD_DIRECT" >&2 + exit 2 + fi + echo "Automatic download and installation of OpenSeadragon successful." + fi + fi fi # Copy OpenSeadragon and all css-files to destination @@ -209,9 +258,8 @@ function copyFiles () { echo "Creating folder $DEST" mkdir -p "$DEST" fi - cp "${ROOT}/${DRAGON}" "$DEST" - cp ${ROOT}/*.js "$DEST" - cp ${ROOT}/*.css "$DEST" + cp ${ROOT}/web/*.js "$DEST" + cp ${ROOT}/web/*.css "$DEST" } # http://stackoverflow.com/questions/14434549/how-to-expand-shell-variables-in-a-text-file @@ -254,9 +302,9 @@ function template () { # srcFolder dstFolder image # Output: SOURCE_IMAGE DEST_IMAGE HIST_IMAGE THUMB function makeImageParams() { - local SRC_FOLDER=$1 - local DEST_FOLDER=$2 - local IMAGE=$3 + local SRC_FOLDER="$1" + local DEST_FOLDER="$2" + local IMAGE="$3" local SANS_PATH=${IMAGE##*/} local BASE=${SANS_PATH%.*} @@ -272,6 +320,8 @@ function makeImageParams() { BLACK_IMAGE="${DEST_FOLDER}/${BASE}.black.png" PRESENTATION_IMAGE="${DEST_FOLDER}/${BASE}.presentation.jpg" TILE_FOLDER="${DEST_FOLDER}/${BASE}_files" + PRESENTATION_TILE_FOLDER="${DEST_FOLDER}/${BASE}.presentation_files" + ALTO_DEST="${DEST_FOLDER}/${BASE}.alto.xml" } # If force is true and image exists, image is deleted and true returned @@ -324,6 +374,8 @@ function makeImages() { local THUMB_OVERLAY_BLACK="${DEST_FOLDER}/${BASE}.black.thumb.png" local PRESENTATION_IMAGE="${DEST_FOLDER}/${BASE}.presentation.jpg" local TILE_FOLDER="${DEST_FOLDER}/${BASE}_files" + local PRESENTATION_TILE_FOLDER="${DEST_FOLDER}/${BASE}.presentation_files" + local ALTO_DEST="${DEST_FOLDER}/${BASE}.alto.xml" if [ ! -f "$SOURCE_IMAGE" ]; then echo "The source image $S does not exists" >&2 @@ -348,6 +400,10 @@ function makeImages() { # TODO: Specify JPEG quality deepzoom "$CONV" -format $IMAGE_DISP_EXT -path "${DEST_FOLDER}/" fi + if shouldGenerate "$FORCE_TILES" "$PRESENTATION_TILE_FOLDER" "tiles"; then + # TODO: Specify JPEG quality + deepzoom "$PRESENTATION_IMAGE" -format $PRESENTATION_IMAGE_DISP_EXT -path "${DEST_FOLDER}/" + fi fi if shouldGenerate "$FORCE_BLOWN" "$WHITE_IMAGE" "overlay"; then @@ -505,14 +561,16 @@ function processALTO() { OVERLAYS="${OVERLAYS}]" return fi - cp "$ALTO" "$DEST" + + cp "$ALTO" "$ALTO_DEST" # Extract key elements from the ALTO local ALTO_COMPACT=`cat "$ALTO_FILE" | sed ':a;N;$!ba;s/\\n/ /g'` # local PTAG=`echo "$ALTO_COMPACT" | grep -o "<PrintSpace[^>]\\+>"` local PTAG=`echo "$ALTO_COMPACT" | grep -o "<Page[^>]\\+>"` local PHEIGHT=`echo $PTAG | sed 's/.*HEIGHT=\"\([^"]\+\)".*/\\1/g'` local PWIDTH=`echo $PTAG | sed 's/.*WIDTH=\"\([^"]\+\)".*/\\1/g'` - ACCURACY=`echo $PTAG | sed 's/.*ACCURACY=\"\([^"]\+\)".*/\\1/g'` + ACCURACY=`echo $PTAG | sed 's/.*PC=\"\([^"]\+\)".*/\\1/g'` + ACCURACY=`echo "scale=2;$ACCURACY*100" | bc` FULL_RELATIVE_HEIGHT=`echo "scale=6;$PHEIGHT/$PWIDTH" | bc | sed 's/^\./0./'` # TODO: Ponder how relative positioning works and why this hack is necessary @@ -590,6 +648,14 @@ function makePreviewPage() { BASE=${SANS_PATH%.*} P="${DEST_FOLDER}/${BASE}.html" + local SSNIP="${BASE}${SPECIFIC_IMAGE_SNIPPET_EXTENSION}" + + if [ -f $SSNIP ]; then + SNIPPET=`cat $SSNIP` + else + SNIPPET="$SNIPPET_FOLDER" + fi + # Used by function caller PAGE_LINK="${BASE}.html" @@ -661,6 +727,21 @@ function makePreviewPage() { Height: \"$IMAGE_HEIGHT\"\ }\ }"$'\n' + if [ ".true" == ".$PRESENTATION" ]; then + PRESENTATION_TILE_SOURCES=" Image: {\ + xmlns: \"http://schemas.microsoft.com/deepzoom/2008\",\ + Url: \"${PRESENTATION_TILE_FOLDER##*/}/\",\ + Format: \"$PRESENTATION_IMAGE_DISP_EXT\",\ + Overlap: \"4\",\ + TileSize: \"256\",\ + Size: {\ + Width: \"$PRESENTATION_WIDTH\",\ + Height: \"$PRESENTATION_HEIGHT\"\ + }\ + }"$'\n' + else + PRESENTATION_TILE_SOURCES="" + fi else TILE_SOURCES=" type: 'legacy-image-pyramid',\ levels:[\ @@ -670,15 +751,20 @@ function makePreviewPage() { height: ${IMAGE_HEIGHT}\ }\ ]"$'\n' + if [ ".true" == ".$PRESENTATION" ]; then + PRESENTATION_TILE_SOURCES=" type: 'legacy-image-pyramid',\ + levels:[\ + {\ + url: '${PRESENTATION_IMAGE##*/}',\ + width: ${PRESENTATION_WIDTH},\ + height: ${PRESENTATION_HEIGHT}\ + }\ + ]"$'\n' + else + PRESENTATION_TILE_SOURCES="" + fi fi THUMB="$THUMB_LINK" - if [ ".true" == ".$PRESENTATION" ]; then - PRESENTATION_LINK=${PRESENTATION_IMAGE##*/} - else - PRESENTATION_LINK="" - PRESENTATION_WIDTH=0 - PRESENTATION_HEIGHT=0 - fi WHITE_LINK=${WHITE_IMAGE##*/} WHITE="$WHITE_LINK" BLACK_LINK=${BLACK_IMAGE##*/} @@ -820,7 +906,15 @@ function makeIndex() { done fi - # UP, PARENT, SRC_FOLDER, DEST_FOLDER, IMAGES_HTML, THUMBS_HTML, SUBFOLDERS_HTML, EDITION_HTML + pushd $SRC_FOLDER > /dev/null + if [ -f $SPECIFIC_FOLDER_SNIPPET ]; then + SNIPPET=`cat $SPECIFIC_FOLDER_SNIPPET` + else + SNIPPET="$SNIPPET_FOLDER" + fi + popd > /dev/null + + # UP, PARENT, SRC_FOLDER, DEST_FOLDER, IMAGES_HTML, THUMBS_HTML, SUBFOLDERS_HTML, EDITION_HTML, SNIPPET ctemplate $FOLDER_TEMPLATE > $PP # Generate pages for sub folders diff --git a/samples/ACE-17950616-0018B.snippet b/samples/ACE-17950616-0018B.snippet new file mode 100644 index 0000000000000000000000000000000000000000..3b02b83016f4166f9fe42c075093a1cb24247f7b --- /dev/null +++ b/samples/ACE-17950616-0018B.snippet @@ -0,0 +1 @@ +<p>Frontpage for the newspaper</p> diff --git a/samples/folder.snippet b/samples/folder.snippet new file mode 100644 index 0000000000000000000000000000000000000000..24fa35fbc5e1069f055a144ae517380439f795d6 --- /dev/null +++ b/samples/folder.snippet @@ -0,0 +1 @@ +<p>Sample images from a 200+ year old Danish newspaper</p> diff --git a/folder_template.html b/web/folder_template.html similarity index 92% rename from folder_template.html rename to web/folder_template.html index 7fddc41ab3343d983c1de560d19ceb2b2b08fee9..e15bb9c919feffc7ed186e4315c9994486aed38e 100644 --- a/folder_template.html +++ b/web/folder_template.html @@ -10,7 +10,7 @@ <body class="folder"> <h1>Quack <span style="color: #999">${SRC_FOLDER}</span></h1> -<div class="foldersnippet">${SNIPPET_FOLDER}</div> +<div class="foldersnippet">${SNIPPET}</div> <!-- TODO: Create decent bread crumbs --> <p>Parent folder: <a href="../index.html">${PARENT}</a></p> @@ -34,5 +34,7 @@ ${SUBFOLDERS_HTML} ${EDITION_HTML} </div> +<p>Generated `date +"%Y-%m-%d %H:%M"`</p> + </body> </html> diff --git a/image_template.html b/web/image_template.html similarity index 94% rename from image_template.html rename to web/image_template.html index 469f3965ae9ecfa0b30e0a82c60322656b9ac0f1..8e074d64aadde77eecf9866569162b5db886c842 100644 --- a/image_template.html +++ b/web/image_template.html @@ -19,7 +19,7 @@ ${IDPREVS} <body class="previewpage"> <h1>Quack <span style="color: #999">${SOURCE_SHORT}</span></h1> -<div class="imagesnippet">${SNIPPET_IMAGE}</div> +<div class="imagesnippet">${SNIPPET}</div> <div id="controlpanel" class="control"> <p class="navigation">${NAVIGATION}</p> @@ -30,7 +30,7 @@ Darkest ${GREY_FIRST}: ${GREY_PERCENT_FIRST}%<br/> Spike ${GREY_SPIKE}: ${GREY_PERCENT_SPIKE}%<br/> Lightest ${GREY_LAST}: ${GREY_PERCENT_LAST}%<br/> Unique greyscale values: ${GREY_UNIQUE}<br/> -ALTO-accuracy: ${ACCURACY}% +ALTO-PC: ${ACCURACY}% <p><input type="checkbox" id="toggle_grid" onClick="toggleGrid();">Grid</input></p> <p><input type="checkbox" id="toggle_textblock" checked="checked" onClick="toggleTextBlock();">TextBlocks</input></p> <p><input type="checkbox" id="toggle_blown" onClick="toggleBlown();">Black/white</input></p> @@ -119,19 +119,12 @@ ${ALTO_ELEMENTS_HTML} <script type="text/javascript"> presentationDragon = OpenSeadragon({ id: "presentation-display", - maxZoomLevel: 2, + maxZoomLevel: 4, showNavigator: false, wrapHorizontal: false, tileSources: { - type: 'legacy-image-pyramid', - levels:[ - { - url: '${PRESENTATION_LINK}', - width: ${PRESENTATION_WIDTH}, - height: ${PRESENTATION_HEIGHT} - }, - ] + ${PRESENTATION_TILE_SOURCES} }}); </script> @@ -140,5 +133,7 @@ ${ALTO_ELEMENTS_HTML} ${GREY_ALL} </pre> +<p>Generated `date +"%Y-%m-%d %H:%M"`</p> + </body> </html> diff --git a/quack.css b/web/quack.css similarity index 77% rename from quack.css rename to web/quack.css index 107ad84c77909a41c0740dff6ccf8e70de018fca..a548c2e3035efa06199555748c3bf5042a43d1f5 100644 --- a/quack.css +++ b/web/quack.css @@ -1,3 +1,55 @@ +/* Basics */ +body { + color: #000; + background: none #F5DEB3; + font-family: verdana, sans-serif; +} +h1, h2, h3, h4, h5, h6 { margin-bottom: 0.2em; } +h1 { color: #32611F } +h2, h3, h4, h5, h6 { color: #1F3D14; } +p { margin-top: 0px; } + +ul { margin-top: 0px; } +code { color: #900; } +q { font-style: italic; } + +a:link { color: #33f; } +a:visited { color: #808; } +a:active { color: #f00; } + +/* Signature */ +.signature { + font-size: smaller; + text-align: right; + clear: both; +} +p.signature a { font-size: smaller ; } +.signature img { float: right; border: none; } + +/* Blocks */ +blockquote { + font-style: italic; + border-style: solid; + border-width: 1px; + border-color: #630; + color: #000; + background: none #ff9; + padding: 2px 5px 2px 4px; +} +blockquote em { font-style: normal; } +pre { + background: none #ffc; + border-style: solid; + border-width: 1px; + white-space: pre; + color: #900; + border-color: #000; + padding: 2px 5px 2px 4px; +} + + +/* Quack specific */ + .xmlvalue { color: #066; } diff --git a/quack.js b/web/quack.js similarity index 100% rename from quack.js rename to web/quack.js diff --git a/quack_folder.js b/web/quack_folder.js similarity index 100% rename from quack_folder.js rename to web/quack_folder.js