#! /bin/bash
# Functions
function init_vars {
if [ "${LDRAW_CAT_HI_RES}" != "" ]; then
export CATALOG_DIR=${HOME}/tmp/LDrawCatalog-high
else
export CATALOG_DIR=${HOME}/tmp/LDrawCatalog
fi
export LAST_DIR=${CATALOG_DIR}/last
export IMG_DIR=${CATALOG_DIR}/img
export FULL_DIR=${CATALOG_DIR}/full
export CAT_DIR=${CATALOG_DIR}/cat
export CSS_FILENAME=LDrawPartsCatalog.css
export MAIN_FILENAME=LDrawPartsCatalog.html
export FULL_FILENAME=LDrawOfflinePartsCatalog.html
export CATALOG=${CATALOG_DIR}/${MAIN_FILENAME}
export FULL_CATALOG=${FULL_DIR}/${FULL_FILENAME}
export CATEGORY_BASE=${CAT_DIR}/LDraw
export ALL_PARTS_LIST=${CATALOG_DIR}/AllLDrawParts.txt
export LAST_ALL_PARTS_LIST=${LAST_DIR}/AllLDrawParts.txt
export PARTS_LIST=${CATALOG_DIR}/LDrawParts.txt
export LAST_PARTS_LIST=${LAST_DIR}/LDrawParts.txt
export BASEPLATES_LIST=${CATALOG_DIR}/LDrawBaseplates.txt
export LAST_BASEPLATES_LIST=${LAST_DIR}/LDrawBaseplates.txt
export PANELS_LIST=${CATALOG_DIR}/LDrawPanels.txt
export LAST_PANELS_LIST=${LAST_DIR}/LDrawPanels.txt
export CATEGORIES_LIST=${CATALOG_DIR}/Categories.txt
export LDRAW_DIR=${HOME}/Library/ldraw
export LDVIEW=/Applications/LDView.app/Contents/MacOS/LDView
}
function print_part_row {
png_filename=${part_filename%.dat}.png
png_size=`file "${IMG_DIR}/${png_filename}" | cut -d , -f 2`
png_width=`echo ${png_size} | cut -d ' ' -f 1`
png_height=`echo ${png_size} | cut -d ' ' -f 3`
if [ "${LDRAW_CAT_HI_RES}" != "" ]; then
(( png_width /= 2 ))
(( png_height /= 2 ))
fi
if [ "${keywords}" != "" ]; then
rowspan=3
else
rowspan=2
fi
echo '
File '${part_filename}'
Name '${desc}' '
if [ "${keywords}" != "" ]; then
echo ' Keywords '${keywords}' '
fi
}
function get_part_desc {
if [ -e "${1}" ]; then
part_desc=`head -n 1 ${1} | sed 's/
$//' | sed -E 's/^0[ ]+//' | tr -d '\n'`
if [[ "${part_desc}" =~ ^~Moved\ to\ ]]; then
old_part_desc=${part_desc}
new_part=`echo "${part_desc}" | sed -E 's/~Moved to //'`
get_part_desc "${new_part}.dat"
fi
fi
}
function process_part {
get_vars_from_line ${*}
export CATEGORY_FILE=${CATEGORY_BASE}${cat}.html
print_part_row >> "${CATEGORY_FILE}"
print_part_row >> "${FULL_CATALOG}"
}
function pre_process_part {
get_vars_from_line ${*}
get_part_desc ${part_filename}
if [[ "${part_desc}" =~ [Bb][Aa][Ss][Ee][Pp][Ll][Aa][Tt][Ee] ]]; then
if [ "${cmdline}" == "" ]; then
echo ${part_filename} >> ${BASEPLATES_LIST}
else
echo ${part_filename}${cmdline} >> ${BASEPLATES_LIST}-cmdline
fi
elif [[ "${part_filename}" =~ ^(4864|6268|4215|2362|4865|4345ap|4345bp)[^0-9] ]]; then
if [ "${cmdline}" == "" ]; then
echo ${part_filename} >> ${PANELS_LIST}
else
echo ${part_filename}${cmdline} >> ${PANELS_LIST}-cmdline
fi
else
if [ "${cmdline}" == "" ]; then
echo ${part_filename} >> ${PARTS_LIST}
else
echo ${part_filename}${cmdline} >> ${PARTS_LIST}-cmdline
fi
fi
}
function find_meta_value {
meta_value=`grep -E '^[ ]*0[ ]+\'$2'[ ]+' $1 | sed -E -e 's/^[ ]*0[ ]+\'$2'[ ]+//' -e 's/
//g'`
}
function find_category {
find_meta_value $1 "!CATEGORY"
if [ "${meta_value}" == "" ]; then
part_cat=`echo ${orig_part_desc} | cut -f 1 -d ' ' | sed -E 's/^[_~=]+//'`
else
part_cat=$meta_value
fi
}
function find_cmdline {
# find_meta_value $1 "!CMDLINE"
# if [ "${meta_value}" != "" ]; then
# part_cmdline=${meta_value}
# else
# unset part_cmdline
# fi
unset part_cmdline
}
function find_keywords {
meta_value=`grep -E '^[ ]*0[ ]+\!KEYWORDS[ ]+' $1 | sed -E -e 's/^[ ]*0[ ]+\!KEYWORDS[ ]+//' -e 's/
//g' -e 's/$/, /'`
if [ "${meta_value}" != "" ]; then
part_keywords=`echo ${meta_value} | sed 's/,$//'`
else
unset part_keywords
fi
}
function print_part_scan {
orig_part_desc=`head -n 1 ${1} | sed 's/
$//' | sed -E 's/^0[ ]+//' | tr -d '\n'`
find_category $1
find_cmdline $1
find_keywords $1
echo -e ${part_cat}${orig_part_desc}${1}${part_cmdline}${part_keywords}
}
function scan_part {
print_part_scan $1 >> ${ALL_PARTS_LIST}
}
function print_style_sheet {
echo 'body
{
font-family: tahoma, sans-serif;
}
p
{
margin-top: 0px;
margin-bottom: 0px;
}
div
{
position: absolute;
}
table
{
border-collapse: collapse;
border: 2px solid #000000;
background-color: #FFFFFF;
padding: 0px;
}
tr
{
page-break-inside: avoid;
}
th
{
background-color: #0080D0;
color: #FFFFFF;
border-bottom: 1px solid #000000;
border-right: 1px solid #00558A;
padding: 4px 8px;
}
th.title
{
background-color: #EEEEEE;
color: #000000;
font-size: 150%;
}
td
{
background-color: #FFFFFF;
border-bottom: 1px solid #BFBFBF;
border-right: 1px solid #BFBFBF;
padding: 2px 4px;
}
td.label
{
text-align: right;
border-right: 0px;
width: 1%;
padding: 2px 0px 2px 4px;
}
table.credits
{
border-collapse: collapse;
border-style: none;
background-color: transparent;
margin: 0px;
width: 100%;
}
td.credits
{
background-color: #EEEEEE;
border-style: none;
padding: 0px;
}
table.credits td
{
background-color: transparent;
color: #808080;
border-style: none;
font-size: 65%;
}
a
{
text-decoration: none;
border-style: none;
}
a:link
{
color: #000080;
}
a:visited
{
color: #0000FF;
}
a:hover
{
text-decoration: underline;
color: #000080;
}
img
{
float: right;
}
a img
{
border-style: none;
}
:link:hover img
{
background-color: #D0E8FF;
}
:visited:hover img
{
background-color: #A0C0FF;
}'
}
function create_style_sheet {
print_style_sheet > "${CATALOG_DIR}/${CSS_FILENAME}"
}
function print_header {
echo '
'${1}' '
echo ''
#echo ' '
echo '
'
}
function print_cat_header {
print_header "${*}" ../
#echo 'Back
'
echo '
'${*}'
'
}
function print_full_header {
print_header "${*}" ../
echo '
'
}
function print_main_header {
print_header "${*}"
echo '
Category
'
}
function create_main_header {
rm -f ${CATALOG}
print_main_header LDraw Parts > "${CATALOG}"
}
function create_full_header {
rm -f ${CATALOG}
print_full_header LDraw Parts > "${FULL_CATALOG}"
}
function create_cat_header {
export CATEGORY_FILE=${CATEGORY_BASE}${1}.html
rm -f ${CATEGORY_FILE}
print_cat_header ${1} > "${CATEGORY_FILE}"
}
function print_footer {
echo '
'
}
function create_cat_footer {
export CATEGORY_FILE=${CATEGORY_BASE}${1}.html
print_footer >> "${CATEGORY_FILE}"
}
function create_full_footer {
print_footer >> "${FULL_CATALOG}"
}
function create_main_footer {
print_footer >> "${CATALOG}"
}
function create_images {
image_size=512
edge_thickness=1
if [ "${LDRAW_CAT_HI_RES}" != "" ]; then
image_size=1024
edge_thickness=2
fi
while [ `stat -f %z ${1}` -gt 0 ]
do
ldview_command_line="${LDVIEW} -LDrawDir=${LDRAW_DIR} ${2} -FOV=0.1 -SaveSnapshots=1 -SaveDir=${IMG_DIR} -SaveWidth=${image_size} -SaveHeight=${image_size} -EdgeThickness=${edge_thickness} -SaveZoomToFit=1 -AutoCrop=1 -SaveAlpha=1 -LineSmoothing=1 -BFC=0 -PreferenceSet=LDPartsCatalog `head -n 50 ${1}`"
$ldview_command_line
if [ $? != 0 ]; then
# LDView occasionally just stops in the middle. Since that is going
# to be a really hard bug to track down, retry the LDView command
# if it fails the first time.
echo LDView failed. Trying one more time.
$ldview_command_line
fi
tail -n +51 ${1} > ${1}.tmp
mv ${1}.tmp ${1}
done
rm -f "${1}"
while read line
do
get_cmdline_vars_from_line ${line}
if [[ "${cmdline}" =~ ^-[cC](.*) ]]; then
default_color=-DefaultColorNumber=${BASH_REMATCH[1]}
else
unset default_color
fi
ldview_command_line="${LDVIEW} -LDrawDir=${LDRAW_DIR} ${2} -FOV=0.1 -SaveSnapshots=1 -SaveDir=${IMG_DIR} -SaveWidth=${image_size} -SaveHeight=${image_size} -EdgeThickness=${edge_thickness} -SaveZoomToFit=1 -AutoCrop=1 -SaveAlpha=1 -LineSmoothing=1 -BFC=0 ${default_color} ${part_filename}"
$ldview_command_line
done < "${1}-cmdline"
rm -f "${1}-cmdline"
}
function create_empty_list {
rm -f ${1}
touch ${1}
}
function create_empty_lists {
create_empty_list ${ALL_PARTS_LIST}
create_empty_list ${PARTS_LIST}
create_empty_list ${PARTS_LIST}-cmdline
create_empty_list ${BASEPLATES_LIST}
create_empty_list ${BASEPLATES_LIST}-cmdline
create_empty_list ${PANELS_LIST}
create_empty_list ${PANELS_LIST}-cmdline
}
function process_parts {
while read line
do
process_part ${line}
done < "${ALL_PARTS_LIST}"
}
function pre_process_parts {
if [ -e ${LAST_PARTS_LIST} ] && [ -e ${LAST_PARTS_LIST}-cmdline ] && [ -e ${LAST_BASEPLATES_LIST} ] && [ -e ${LAST_BASEPLATES_LIST}-cmdline ] && [ -e ${LAST_PANELS_LIST} ] && [ -e ${LAST_PANELS_LIST}-cmdline ]; then
cp ${LAST_PARTS_LIST} ${PARTS_LIST}
cp ${LAST_PARTS_LIST}-cmdline ${PARTS_LIST}-cmdline
cp ${LAST_BASEPLATES_LIST} ${BASEPLATES_LIST}
cp ${LAST_BASEPLATES_LIST}-cmdline ${BASEPLATES_LIST}-cmdline
cp ${LAST_PANELS_LIST} ${PANELS_LIST}
cp ${LAST_PANELS_LIST}-cmdline ${PANELS_LIST}-cmdline
return
fi
echo Preprocessing part information...
while read line
do
pre_process_part ${line}
done < "${ALL_PARTS_LIST}"
cp ${PARTS_LIST} ${LAST_DIR}/
cp ${PARTS_LIST}-cmdline ${LAST_DIR}/
cp ${BASEPLATES_LIST} ${LAST_DIR}/
cp ${BASEPLATES_LIST}-cmdline ${LAST_DIR}/
cp ${PANELS_LIST} ${LAST_DIR}/
cp ${PANELS_LIST}-cmdline ${LAST_DIR}/
}
function process_command_line {
if [ "${1}" == "-hi" ]; then
echo Generating high-resolution images.
LDRAW_CAT_HI_RES=1
else
unset LDRAW_CAT_HI_RES
fi
}
function verify_dir {
if [ ! -d "${1}" ]; then
mkdir -p "${1}"
fi
if [ ! -d "${1}" ]; then
echo Error creating directory ${1}.
exit
fi
}
function verify_settings {
verify_dir "${LAST_DIR}"
verify_dir "${CATALOG_DIR}"
verify_dir "${IMG_DIR}"
verify_dir "${CAT_DIR}"
verify_dir "${FULL_DIR}"
if [ ! -d ${LDRAW_DIR} ]; then
echo LDraw directory not found at ${LDRAW_DIR}
exit
fi
}
function scan_parts {
cd ${LDRAW_DIR}/parts
if [ -e ${LAST_ALL_PARTS_LIST} ]; then
cp ${LAST_ALL_PARTS_LIST} ${ALL_PARTS_LIST}
else
echo Scanning parts...
for partFile in *.dat
do
scan_part ${partFile}
done
echo Sorting parts list...
# Set locale to UTF-8 for sorting, since LDraw officially uses UTF-8
export LC_ALL=UTF-8
sort -f ${ALL_PARTS_LIST} > ${ALL_PARTS_LIST}.tmp
mv ${ALL_PARTS_LIST}.tmp ${ALL_PARTS_LIST}
cp ${ALL_PARTS_LIST} ${LAST_ALL_PARTS_LIST}
fi
cut -d -f 1 ${ALL_PARTS_LIST} | sort -u > ${CATEGORIES_LIST}
}
function generate_part_images {
num_imgs=`ls ${IMG_DIR}/ | wc -l`
num_parts=`cat ${ALL_PARTS_LIST} | wc -l`
if [ ${num_imgs} != ${num_parts} ]; then
echo Generating panel part images...
create_images ${PANELS_LIST} -cg30,225,275000
echo Generating baseplate part images...
create_images ${BASEPLATES_LIST} -cg30,45,550000
echo Generating standard part images...
create_images ${PARTS_LIST} -cg30,45,275000
else
echo Images already generated.
fi
}
function print_cat_row {
echo '
'${*}'
'
}
function create_cat_row {
print_cat_row "${*}" >> "${CATALOG}"
}
function generate_html {
echo Generating HTML...
create_style_sheet
create_full_header
create_main_header
while read line
do
create_cat_header "${line}"
create_cat_row "${line}"
done < "${CATEGORIES_LIST}"
create_main_footer
process_parts
create_full_footer
while read line
do
create_cat_footer ${line}
done < "${CATEGORIES_LIST}"
echo HTML created.
}
function get_cmdline_vars_from_line {
if [[ "${*}" =~ ([^]*)([^]*) ]]; then
part_filename=${BASH_REMATCH[1]}
cmdline=${BASH_REMATCH[2]}
fi
}
function get_vars_from_line {
if [[ "${*}" =~ ([^]*)([^]*)([^]*)([^]*)([^]*) ]]; then
cat=${BASH_REMATCH[1]}
desc=${BASH_REMATCH[2]}
part_filename=${BASH_REMATCH[3]}
cmdline=${BASH_REMATCH[4]}
keywords=${BASH_REMATCH[5]}
fi
}
# Main program
process_command_line ${*}
init_vars
verify_settings
create_empty_lists
scan_parts
pre_process_parts
generate_part_images
generate_html
rm -f ${ALL_PARTS_LIST}