.. _CherryPy: http://www.cherrypy.org/
.. _Jinja2: http://jinja.pocoo.org/2/
+
System dependencies
===================
-You need `LaTeX`_ and `MetaPost`_ to compile the documents. The
-`texlive-base`, `texlive-metapost`, and `context` `Debian`_ packages
-should cover you. You can avoid the context dependency with some
-`legwork`_.
+You need `LaTeX`_ to compile the documents. The
+`texlive-latex-recommended`_, `texlive-latex-extra`_, and `pgf`_
+`Debian`_ packages should cover you.
.. _LaTeX: http://www.latex-project.org/
-.. _MetaPost: http://tug.org/metapost.html
+.. _texlive-latex-recommended: http://packages.debian.org/lenny/texlive-latex-recommended
+.. _texlive-latex-extra: http://packages.debian.org/lenny/texlive-latex-extra
+.. _pgf: http://packages.debian.org/lenny/pgf
.. _Debian: http://www.debian.org/
-.. _legwork: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=465107
Commands
========
-The web interface (chem_web.py) is a web-daemon using web.py and it's build in htmlserver.
-Standard command for starting the daemon::
+The web interface (:file:`bin/chem_web.py`) is a web-daemon using
+CherryPy. Standard command for starting the daemon::
- $ chem_web.py -a 192.168.1.2:55555
+ $ bin/chem_web.py -a 192.168.1.2 -p 55555
Standard command for stopping the daemon::
- $ chem_web.py --stop
+ $ bin/chem_web.py --stop
From the command line, you can validate CAS#s (and possibly other fields) with::
- $ python chem_db.py -f current/inventory.db -V
+ $ bin/chem_db.py -f example/inventory.db -V
Database format
===============
-text_db.py provides the python interface to this format. The basic
-idea was to produce and use files which were M$-Excel-compatible,
-since future users might not want to maintain this interface. A brief
-example inventory.db file is included in the examples directory.
+:mod:`chemdb.db.text` provides the python interface to this format.
+The basic idea was to produce and use files which were
+M$-Excel-compatible, since future users might not want to maintain the
+ChemDB interface. A brief example :file:`inventory.db` file is
+included in the examples directory.
* Tab-delimited ('\t') fields
* Endline-delimited ('\n') records
it contains a tab-delimiteded list of long field names.
* Blank lines are ignored.
-The fields H, F, R, and S are the NFPA Health, Fire, Reactivity, and Special Hazards (NFPA diamond).
+The fields H, F, R, and S are the NFPA Health, Fire, Reactivity, and
+Special Hazards (NFPA diamond).
* Blue: Health Hazard
0 Hazard no greater than ordinary material
Contents
========
-* README this file
-* DEPENDENCIES list of dependencies (libraries, python modules, etc.)
-* COPYING GNU General Public License, version 3
-* text_db.py python interface to the above db format
-* chem_db.py chem-inventory specific functionality such as
- * CAS # validation,
- * a Material Saftey Data Sheet (MSDS) manager,
- * document-generation drivers, and
- * a simple command line interface.
-* current store the current database file.
-* backup store previous (timestamped) database files.
- You may want to clean this out occasionally.
-* MSDS store Material Saftey Data Sheets by database index number
-* docs latex (and metapost) sources for document generation.
-* chem_web.py daemonized web bindings to chem_web.py
-* ssl Secure Socket Layer (SSL) key and certificate generation tests.
+ bin (executibles)
+ |-- chem_db.py (command line interface)
+ `-- chem_web.py (web interface)
+ chemdb (python package)
+ contrib (useful but non-critical utilities)
+ `-- ssl (SSL key/certificate generation)
+ COPYING (GNU GPLv3 license)
+ DEPENDENCIES (description of software dependencies)
+ example (example data for demonstrations and testing)
+ |-- inventory.db (example inventory database)
+ `-- static (example directory for statically served content)
+ `-- MSDS (example MSDS storage location)
+ `-- 0.html (dummy MSDS for acetic acid)
+ README (this file)
+ template
+ |-- doc (LaTeX source for PDF generation)
+ `-- web (Jinja2 templates for HTML generation)
+ update_copyright.py (script automating copyright blurb maintenance)
Generated files and directories
-------------------------------
============ =======================================================================
-templates quasi-HTML templates for pages generated chem_web.py
+backup store database file snapshots from every change
chem_web.pid store the Process ID (PID) for a daemonized chem_web.py process
chem_web.log log chem_web activity (maintained between runs, so remove periodically)
============ =======================================================================
example, to generate a door warning for the front door use
door_warning(lambda r: r['Disposed'] == '')
or to generate the warning for the fridge
- door_warning(lambda r: r['Location'] == 'Refrigerator')
+ door_warning(lambda r: r['Disposed'] == '' and r['Location'] == 'Refrigerator')
Note that valid_record defaults to the first example.
"""
- pp = DBPrettyPrinter(self.db)
- all_ids = range(self.db.len_records())
-
# Search the database to find the nasties
NFPA_maxs = {'H':0, 'F':0, 'R':0, 'O':[]}
Mutagens = []
array.append(record['db_id'])
## generate the output
- # first, update the NFPA grapic code
- if 'OX' in NFPA_maxs['O'] : OX = 'y'
- else : OX = 'n'
- if 'W' in NFPA_maxs['O'] : W = 'y'
- else : W = 'n'
- os.system('%s %d %d %d %s %s > %s'
- % (os.path.join(self.doc_root, 'gen_NFPA.sh'),
- NFPA_maxs['H'], NFPA_maxs['F'], NFPA_maxs['R'], OX, W,
- os.path.join(self.doc_root, 'mp', 'NFPA.mp')))
+ # setup the NFPA grapic
+ oxstring = 'oxidizer' if 'OX' in NFPA_maxs['O'] else None
+ wstring = 'nowater' if 'W' in NFPA_maxs['O'] else None
+ extra_specials = [
+ x for x in NFPA_maxs['O'] if x not in ['OX', 'W']]
+ esstring = None
+ if len(extra_specials) > 0:
+ esstring = 'special={%s}' % (
+ ','.join([x for x in extra_specials]))
+ NFPA_maxs['special_args'] = ', '.join([
+ x for x in [oxstring, wstring, esstring] if x != None])
+ string = """
+\\begin{center}
+ \\Huge
+ \\firediamond{health=%(H)s, flammability=%(F)s, reactivity=%(R)s,
+ %(special_args)s}
+\\end{center}
+""" % NFPA_maxs
# now generate a list of the nasties ( Amount & ID & Name )
- string = "\\begin{tabular}{r r l}\n"
+ string += """
+\\vspacer
+
+\\contfont
+
+\\begin{tabular}{r r l}
+"""
for field,name,array in zip(['H', 'F', 'R', 'O'],
['Health', 'Fire',
'Reactivity', 'Other'],
@cherrypy.expose
def door_warning_pdf(self, location=None):
self.db._refresh()
- regexp = re.compile(location, re.I) # Case insensitive
- path = dgen.door_warning(lambda r: regexp.match(r['Location']))
+ if location == None:
+ valid = lambda r: r['Disposed'] == ''
+ else:
+ regexp = re.compile(location, re.I) # Case insensitive
+ valid = lambda r: r['Disposed'] == '' and regexp.match(r['Location'])
+ path = self.docgen.door_warning(valid_record=valid)
cherrypy.response.headers['Content-Type'] = 'application/pdf'
return file(path, 'rb').read()
#ID Name Amount CAS# Cat# Vendor Recieved Location H F R O M C T Disposed Note
#ID Name Amount CAS# Catalog # Vendor Date Recieved Location NFPA Health NFPA Fire NFPA Reactivity NFPA Other Mutagen ('M' or '') Carcinogen ('C' or '') Teratogen ('T' or '') Date disposed Note
-0 Acetic Acid 500 ml 64-19-7 A35-500 Fisher 7/5/2001 acidic liquids 3 2 1
-1 Glycine 500 g 56-40-6 15527-013 Life Tech. 1/16/2000 non-hazardous 1 0 0 Avoid strong oxidizers
-2 Sodium Chloride (NaCl) 500 g 7647-14-5 JT4058-1 VWR/Fisher 10/22/2000 non-hazardous 1 0 0
+0 Acetic Acid (CH3COOH) 500 ml 64-19-7 A35-500 Fisher 7/5/2001 acidic liquids 3 2 1
+1 Ammonium Persulfate ((NH4)2S2O8) 100 g 7727-54-0 15523-012 Life Tech. 1/16/2000 oxidizing solids 3 0 3 OX
+2 Glycerin Solution 50% (C3H5(OH)3) 500 ml 56-81-5,7647-01-0,7732-18-5 VW3410-2 VWR 1/17/2001 corrosive liquids 1 0 1 M T Labled H2 F0 R0 in NFPA diamond on the bottle. Corrosive. Avoid strong bases and oxidizers.
+3 Glycine (NH2CH2COOH) 500 g 56-40-6 15527-013 Life Tech. 1/16/2000 non-hazardous 1 0 0 Avoid strong oxidizers
+4 Phenol (C6H5OH) 100 g 108-95-2 P1037 Sigma 1/17/2006 reactive solids 3 2 0 M C T Avoid strong oxidizers (especially calcium hypochlorite), acids, and halogens.
+5 Sodium Chloride (NaCl) 500 g 7647-14-5 JT4058-1 VWR/Fisher 10/22/2000 non-hazardous 1 0 0
+6 Sodium Hydroxide (NaOH) 50% (w/w) solution 500 ml 1310-73-2,7732-18-5 JT3727-1 VWR/JTBaker 10/22/2000 basic liquids 3 0 2 W
-# Produce html, pdf, and dvi output from latex source
-# W. Trevor King, 2008, version 0.2
-# This file is in the public domain.
-#
+# Produce pdf output from LaTeX source
+# Copyright (C) 2008-2010 W. Trevor King
+
# exposed targets :
-# all : generate each of the outputs (pdf, html, dvi) and call view
+# all : generate each output file and call view
# view : call '$(PDF_VIEWER) main.pdf &' to see the pdf file
-# install : call install_% for pdf, html, dvi, and dist
# clean : semi-clean and remove the $(GENERATED_FILES) as well
# semi-clean : remove all intermediate $(TEMP_FILES) used during generation
#
# pdf : generate the pdf file (Portable Document Format)
-# install_pdf : install the dvi file (currently no action)
-# html : generate html directory ready for posting
-# install_html : scp the html directory to $(INSTALL_HTML)
-# dvi : generate main.dvi (DeVice Independent file)
-# install_dvi : install the dvi file (currently no action)
-# dist : gen. $(DOC_NAME)-$(VERSION).tar.gz containing $(DIST_FILES)
-# install_dist : install the dist file (currently no action)
-#
-# images : call for generation of all images in $(IMAGES)
-
-DOC_NAME = chem_inventory
-VERSION = 0.2
-
-# I like to keep my images in seperate directories, where any processing
-# they may need woln't clutter up the base directory with temp files.
-# To control these, this Makefile calls the Makefiles in the IMAGE_DIRS,
-# so make sure they exist, and have the following targets:
-# clean : remove all generated files
-# semi-clean : remove all intermediate files
-# for each image in IMAGE, you must have a rule that generates it,
-# see 'image generation rules' below
-IMAGES = mp/NFPA.1
-IMAGE_DIRS = mp
# Non image source files
-SOURCE_FILES = main.tex *.tex
-# And anything else you'd like to distribute
-OTHER_FILES = README Makefile
+MAIN_SOURCE_FILES = main.tex *.tex
+NFPA_704_SOURCE_FILES = nfpa_704.tex nfpa_704.sty
-DIST_FILES = $(SOURCE_FILES) $(OTHER_FILES) $(IMAGE_DIRS)
+# Files removed on clean or semi-clean
+TEMP_FILES = *[.]aux *[.]log *[.]out *[.]bak
-# Select where to put things when you call the dist and install targets
-DIST_DIR = $(DOC_NAME)-$(VERSION)
-DIST_NAME = $(DOC_NAME)-$(VERSION).tar.gz
-INSTALL_PDF = $(HOME)/rsrch/notes
-INSTALL_DVI =
-INSTALL_HTML = einstein:./public_html/rsrch/papers/$(DOC_NAME)
-# interpreted as latex by latex2html, so escape the '~' to '\~{}'
-TILDE = "%7E"
-CSS_PATH = "/$(TILDE)wking/shared/style_l2h.css"
+# Files generated by Python
+PYTHON_GENERATED_FILES = *_data.tex inventory_title.tex main.tex
-# Files removed on clean or semi-clean
-TEMP_FILES = *[.]aux *[.]log *[.]out *[.]bak \
- *.png *.eps
# Files removed only on clean
-GENERATED_FILES = $(DIST_NAME) \
- rm -f main.pdf main.dvi html *.pdf
+GENERATED_FILES = *.pdf $(PYTHON_GENERATED_FILES)
PDF_VIEWER = xpdf # you can also try evince, acroread, 'xpdf -view H', etc.
-## image generation rules, to handle the images in $(IMAGES)
-
-mp/NFPA.1 : mp/NFPA.mp
- $(MAKE) -C mp images
-
-
-
-### The remaining rules shouldn't need to be changed
-
-# pdf, dvi, and html depend on images
-images : $(IMAGES)
-
-
## Big targets
all : pdf view # html dvi view
view : pdf
$(PDF_VIEWER) main.pdf &
-install : install_pdf install_html install_dvi install_dist
-
-clean : semi-clean $(IMAGE_DIRS:%=%_clean)
+clean : semi-clean
rm -rf $(GENERATED_FILES)
-semi-clean : $(IMAGE_DIRS:%=%_semi-clean)
+semi-clean :
rm -f $(TEMP_FILES)
## Mid-level indirection targets
-
-# indirection, so we can have short names like 'pdf'
-# without rebuilding when it's not neccessary
-pdf : main.pdf
-dvi : main.dvi
-dist : $(DIST_NAME)
-
-
-## Installation targets
-
-install_pdf :
-install_html : html clean_html_image_dirs
- scp -r html $(INSTALL_HTML)
-install_dvi :
-install_dist :
-
+pdf : main.pdf nfpa_704.pdf
## The meat of the generation
# generate the pdf output directly with pdflatex
-main.pdf : main.aux $(SOURCE_FILE) images
- pdflatex main.tex
-
-# generate html files, including the DIST_FILES in a subdir.
-# latex2html requires main.aux to generate figure numbers
-# main.pdf is for the '$(DOC_NAME).pdf' link in the footer
-# (see ~/.latex2html-init)
-html : $(SOURCE_FILES) main.aux main.pdf
- latex2html -split 1 -white -notransparent -html_version 3.2 \
- -t $(DOC_NAME) -dir html -mkdir \
- -noshort_extn -top_navigation -bottom_navigation \
- -up_url '../' -up_title 'Papers' \
- -show_section_numbers \
- -style $(CSS_PATH) \
- main.tex # generate the html
- if [ ! -d html/src ]; then mkdir html/src ; fi # mk src if it doesn't exist yet
- cp -r $(DIST_FILES) html/src/ # move the source files into html/src
- cp main.pdf html/$(DOC_NAME).pdf # move the pdf in so we can link to it
-
-# generate the .aux file which contains labels for referencing
-# needed to correctly number references in the pdf and html output.
-# (Clash between latex and pdflatex's .aux files? semi-clean fixes)
-# -draftmode makes pdflatex ignore images and not make a pdf (faster)
-main.aux : *.tex images
- pdflatex -draftmode main.tex
-
-# to stretch our .tex files a bit more, make a dvi as well :p
-# run twice to straighten out and TOC or references issues
-main.dvi : $(SOURCE_FILES) images
- latex main.tex
- latex main.tex
-
-# generate a gzipped tar file containing the DIST_FILES
-$(DIST_NAME) : $(DIST_FILES)
- mkdir $(DIST_DIR)
- cp $(DIST_FILES) $(DIST_DIR)
- tar -chozf $(DIST_NAME) $(DIST_DIR)
- rm -rf $(DIST_DIR)
-
-
-## IMAGE_DIR handling rules
-
-# call clean for any image directory
-%_clean : %
- $(MAKE) -C $< clean
-
-# call semi-clean for any image directory
-%_semi-clean : %
- $(MAKE) -C $< semi-clean
-
-# clean and junk that was in the working image directories
-clean_html_image_dirs : $(IMAGE_DIRS:%=%_html_dir_clean)
+main.pdf : $(MAIN_SOURCE_FILES)
+ pdflatex -interaction=batchmode -draftmode $<
+ pdflatex -interaction=batchmode $<
-# call clean for any image directory in the html/src directory
-%_html_dir_clean : %
- $(MAKE) -C html/src/$< clean
+nfpa_704.pdf : $(NFPA_704_SOURCE_FILES)
+ pdflatex -interaction=batchmode -draftmode $<
+ pdflatex -interaction=batchmode $<
This directory just contains the latex and infrastructure to make nice
documents from the data.
-The `mp' directory contains metapost source and assorted
-infrastructure for building and previewing the graphics.
-
-Note that due to my wimpy Makefile rules, you may need to make a door
-warning before making an inventory, in order to avoid
- make: *** No rule to make target `mp/NFPA.mp', needed by `mp/NFPA.1'. Stop.
+The `nfpa_704.sty' package contains LaTeX code for the \firediamond macro.
+For usage samples, see `nfpa_704.tex'.
-% \documentclass[letterpaper]{article} % line moved to main.
% Paper for posting on the lab door
% as per
+% http://www.drexelsafetyandhealth.com/lab-chem.htm#chpe7
+% and
+% href="http://www.drexelsafetyandhealth.com/lab-chem.htm#chpe10
-% setup the margins,
+% setup the margins
\topmargin -0.5in
\headheight 0.0in
\headsep 0.0in
\oddsidemargin -0.5in
\textwidth 7.5in
-%% Graphics packages
-
-\usepackage{graphicx} % to include images
-% if pdftex doesn't recognize the type, it's mps
-% DeclareGraphicsRule{ext}{type}{sizefile}{command}
-\DeclareGraphicsRule{*}{mps}{*}{}
-% latex and latex2html can handle Metapost's eps output without modification
+\usepackage{nfpa_704} % \firediamond
% define a vertical strut for table spacing
\newcommand{\Tstrut}{\rule{0pt}{2.6ex}}
\thispagestyle{empty} % suppress page numbering
\sffamily % switch to sans-serif
-
\begin{center}
-\includegraphics[width=3in]{mp/NFPA.1}
-\vspacer
-
-\contfont
\input{door_data}
\vfill
\input{contact}
\vspacer
-Generated \today\ by chem\_db.py
+Generated \today\ by ChemDB.
\end{center}
\oddsidemargin -0.5in
\textwidth 7.5in
-%% Graphics packages
-
-\usepackage{graphicx} % to include images
-% if pdftex doesn't recognize the type, it's mps
-% DeclareGraphicsRule{ext}{type}{sizefile}{command}
-\DeclareGraphicsRule{*}{mps}{*}{}
-% latex and latex2html can handle Metapost's eps output without modification
+\usepackage{nfpa_704} % \firediamond
% N of M style page numbering
\usepackage{fancyhdr}
\begin{center}
{\headfont \input{inventory_title}}\\
\contfont
-Generated \today\ by chem\_db.py\\
+Generated \today\ by ChemDB.\\
\vskip 10pt
\end{center}
+++ /dev/null
-MPS = NFPA
-
-TEMP_FILES = $(MPS:%=%.mp[a-z]) $(MPS:%=%.log) mp* texnum.mpx NFPA.mp
-GENERATED_FILES = $(MPS:%=%.[0-9]*) sample.log sample.aux sample.pdf
-
-#PDFVIEWER = gv
-PDFVIEWER = xpdf
-#PDFVIEWER = evince
-
-images : $(MPS:%=%.1)
-
-all : view
-
-view : sample.pdf
- $(PDFVIEWER) sample.pdf &
-
-clean : semi-clean
- rm -f $(GENERATED_FILES)
-
-semi-clean :
- rm -f $(TEMP_FILES)
-
-# Dummy NFPA.mp in case the pdf doesn't need it,
-# since ./doc/Makefile always thinks the pdf needs NFPA.1
-NFPA.mp : gen_NFPA.sh
- $< 9 9 9 y y > $@
-
-# generate a pdf containing all mp images for previewing-troubleshooting
-# depend on the first image from each mp file
-sample.pdf : sample.tex images
- pdflatex sample.tex
-
-# if we call for the first image from an mp file, make them all
-%.1 : %.mp %_c.mp
- mpost "\$(^:%=input %;)"
+++ /dev/null
-
-%% NFPA warning triangle
-boolean labels;
-labels := false; % turn on debugging labels
-
-% sizing
-numeric u;
-
-u := 2cm; % unit, for overall scaling
-
-% line thicknesses
-numeric cyl_thickness, wire_thickness;
-border := 1pt; % thickness of the box outlines
-
-% colors
-color hcolor, fcolor, rcolor, ocolor, bcolor;
-hcolor := (0,0,1); % health
-fcolor := (1,0,0); % fire
-rcolor := (1,1,0); % reactivity
-ocolor := white; % other
-bcolor := black; % border
-
-% return a diamond path
-vardef diamond(expr radius) =
- save P;
- path P;
- P := (-radius,0) -- (0,radius) -- (radius,0) -- (0,-radius) -- cycle;
- P
-enddef;
-
-def NFPA(expr center, radius, h, f, r, o) =
- save p, hr, qr;
- pair p;
- numeric hr, hr;
- hr := radius/2;
- qr := radius/4;
- % draw the background colors
- fill diamond(hr) shifted (center-(hr,0)) withcolor hcolor;
- fill diamond(hr) shifted (center+(0,hr)) withcolor fcolor;
- fill diamond(hr) shifted (center+(hr,0)) withcolor rcolor;
- fill diamond(hr) shifted (center-(0,hr)) withcolor ocolor;
- % draw the borders
- draw diamond(radius) shifted center withpen pencircle scaled border
- withcolor bcolor;
- p := (hr,hr);
- draw p -- -p shifted center withpen pencircle scaled border
- withcolor bcolor;
- p := (hr,-hr);
- draw p -- -p shifted center withpen pencircle scaled border
- withcolor bcolor;
- % add the text
- label(h, center-(hr,0));
- label(f, center+(0,hr));
- label(r, center+(hr,0));
- % btex 4 etex,
- % btex ox etex;
- % btex \sout{W} etex;
- label(o, center-(0,hr));
-enddef;
-
-beginfig(1)
- NFPA(origin, u,
- h,
- f,
- r,
- o);
-
-endfig;
-
-end
+++ /dev/null
-NFPA.mp and NFPA_c.mp are for generating an NFPA warning diamond. The
-diamond code and figure definitions are in NFPA_c.mp (c for code :p).
-NFPA.mp extracts the TeX for creating the symbols for the corners.
-Because this infomation will change with time (depending on the
-chemicals in the lab), you have to recreate NFPA.mp to get an image
-with the current values. Calling
- $ gen_NFPA.sh <H> <F> <R> <ox?> <w?> > NFPA.mp
-will generate the proper NFPA.mp file. As an explicit example,
-try the complete pdf generation and viewing commands
- $ gen_NFPA.sh 4 3 3 y y > NFPA.mp
- $ make view
-NFPA_c.mp contains the common code for drawing warning diamonds.
-sample.tex is just a simple latex script for previewing diamonds.
+++ /dev/null
-#!/bin/bash
-#
-# Generate NFPA.mp for given hazard levels
-
-HEALTH=$1
-FIRE=$2
-REACT=$3
-OX=$4
-W=$5
-
-REDIRECT=0 # if != 0, then print directly to OFILE
-OFILE="NFPA.mp"
-
-# stdout redirection from Advanced Bash Scripting Guide
-# http://tldp.org/LDP/abs/html/x16355.html#REASSIGNSTDOUT
-if [ $REDIRECT -ne 0 ]
-then
- exec 6>&1 # Link file descriptor #6 with stdout.
- # Saves stdout.
- # stdout replaced with file "logfile.txt".
- exec > $OFILE
-fi
-
-echo "verbatimtex
-
-\font\bigfont=cmss17 at 50pt
-\font\medfont=cmss17 at 25pt
-\font\smfont=cmss17 at 20pt
-\bigfont
-
-% center two hboxes (containing e.g. \OX and \W)
-\def\vert#1#2{\vbox{\halign{\hfil##\hfil\cr
-\hbox{#1}\cr
-\hbox{#2}\cr}}}
-
-% strikethrough (or strikeout) from Chapter 21 of the TeXbook
-% the height of the strikeout has been raised from 0.8 to 0.9ex
-% to make it look nicer when escaping a purely capital letter (W).
-\def\sout#1{{%
- \setbox0=\hbox{#1}%
- \dimen0 0.9ex\dimen1\dimen0\advance\dimen1 by 0.4pt
- \rlap{\leaders\hrule height \dimen1 depth -\dimen0\hskip\wd0}%
- \box0
-}}
-
-\def\OX{{OX}}
-\def\W{{\sout{W}}}
-
-etex
-
-%% NFPA values :
-% set in the call to mpost, e.g.
-% $ mpost 'input NFPA.mp; input NFPA_c.mp'
-picture h,f,r,o;
-h := btex $HEALTH etex;
-f := btex $FIRE etex;
-r := btex $REACT etex;"
-
-if [ "$OX" == "y" ] && [ "$W" == "y" ]
-then
- echo "o := btex {\smfont \vert{\OX}{\W}} etex;"
-elif [ "$OX" == "y" ]
-then
- echo "o := btex {\medfont \OX} etex;"
-elif [ "$W" == "y" ]
-then
- echo "o := btex {\medfont \W} etex;"
-else # both are "n"
- echo "o := btex etex"
-fi
-
-if [ $REDIRECT -ne 0 ]
-then
- # Restore stdout and close file descriptor #6.
- exec 1>&6 6>&-
-fi
-
-exit 0
+++ /dev/null
-\documentclass{article}
-\usepackage{graphicx}
-\usepackage{fullpage}
-
-\DeclareGraphicsRule{*}{mps}{*}{} % if tex doesn't recognize the type, it's mps
-
-% NFPA for 'NFPA.mp image'
-\newcommand{\NFPA}[1]{piezo.#1 \includegraphics{NFPA.#1}\vspace{1cm} \\}
-
-\begin{document}
-\centering
-\NFPA{1}
-\end{document}
--- /dev/null
+% nfpa_704.sty, a package for generating NFPA fire diamonds.
+% Version 0.1
+%
+% Copyright (C) 2010 W. Trevor King <wking@drexel.edu>
+
+% See
+% http://en.wikipedia.org/wiki/NFPA_704
+% for more information on the NFPA 704 "fire diamond".
+
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+\ProvidesPackage{nfpa_704}
+ [2010/08/24 v0.1 NFPA flammability diamond]
+
+\RequirePackage{forloop} % program flow control
+\RequirePackage{tikz} % graphics
+\RequirePackage{ulem} % strikethrough (or strikeout)
+\RequirePackage{xkeyval} % handling x=y-type options
+\normalem % use the standard \em, not ulem's version
+
+% Raise \ulem's \sout height a bit to look nicer striking out capital
+% letters like "W".
+\def\nfpa@caps@sout{\bgroup \ULdepth=-1ex \ULset}
+
+\newcommand{\nowater}{\nfpa@caps@sout{W}}
+\newcommand{\oxidizer}{OXY}
+\newcommand{\asphixiant}{SA}
+
+\newcommand{\nfpa@firediamond@radius}{}
+\newcommand{\nfpa@firediamond@health}{}
+\newcommand{\nfpa@firediamond@flammability}{}
+\newcommand{\nfpa@firediamond@reactivity}{}
+\newcommand{\nfpa@firediamond@extraspecial}{}
+
+\define@key{firediamond}{radius}{\def\nfpa@firediamond@radius{#1}}
+\define@key{firediamond}{health}{\def\nfpa@firediamond@health{#1}}
+\define@key{firediamond}{flammability}{\def\nfpa@firediamond@flammability{#1}}
+\define@key{firediamond}{reactivity}{\def\nfpa@firediamond@reactivity{#1}}
+\define@boolkey{firediamond}{nowater}[true]{}
+\define@boolkey{firediamond}{oxidizer}[true]{}
+\define@boolkey{firediamond}{asphixiant}[true]{}
+\define@key{firediamond}{special}{\def\nfpa@firediamond@extraspecial{#1}}
+\presetkeys{firediamond}{% set default values
+ radius=3.5em,
+ health=0,flammability=0,reactivity=0,
+ nowater=false,oxidizer=false,asphixiant=false,
+ special={}}%
+ {}% post-process input parameters
+
+\newcounter{nfpa@firediamond@ispecial}
+\newcounter{nfpa@firediamond@jspecial}
+\newcommand{\nfpa@firediamond@clearspecial}{%
+ \setcounter{nfpa@firediamond@ispecial}{0}%
+}
+
+% Add a special string (e.g. \nowater, \oxidizer, ...).
+\newcommand{\nfpa@firediamond@addspecial}[1]{%
+ \addtocounter{nfpa@firediamond@ispecial}{1}%
+ \expandafter\gdef\csname nfpa@firediamond@special@\alph{nfpa@firediamond@ispecial}\endcsname{#1}%
+}
+
+% Add a special string, evaluating the value of #1 immediately. This
+% is important in the case of \nfpa@firediamond@makespecial's \@ii, as
+% it will be set to \@nil after looping. However, it will fail for some
+% macros. For example, \nfpa@firediamond@xaddspecial{\nowater} raises
+% ! Undefined control sequence.
+% \ULset ...ce \ULdepth .4\p@ \fi \def \UL@leadtype
+% {\leaders \hrule \@height ...
+\newcommand{\nfpa@firediamond@xaddspecial}[1]{%
+ \addtocounter{nfpa@firediamond@ispecial}{1}%
+ \expandafter\xdef\csname nfpa@firediamond@special@\alph{nfpa@firediamond@ispecial}\endcsname{#1}%
+}
+
+\newcommand{\nfpa@firediamond@getspecial}[1]{%
+ \csname nfpa@firediamond@special@\alph{#1}\endcsname%
+}
+
+% Print the contents of the special quadrant and beyond.
+%
+% From http://www.nfpa.org/assets/files/PDF/ROP/704-A2006-ROP.pdf
+%
+% 704-4 Log #CP4 Final Action: Accept
+% (8.2.3 and Figures 9.1(a) and (c))
+% ...
+% SUBSTANTIATION: The committee expressed concern that for the
+% relatively few chemicals requiring both an "OX" and "W" symbols in
+% the special hazards quadrant, there wouldn’t be enough room for
+% both to appear in the prescribed sizes for clear visibility. The
+% committee believed the "W" is the primary hazard and should be
+% displayed inside the quadrant, with the "OX" outside the
+% quadrant. It was reported that many large companies have adopted
+% this practice successfully already. The figures were enhanced for
+% user-friendliness.
+\newcommand{\nfpa@firediamond@makespecial}{%
+ \nfpa@firediamond@clearspecial{}%
+ \ifKV@firediamond@nowater\nfpa@firediamond@addspecial{\nowater}\fi%
+ \ifKV@firediamond@oxidizer\nfpa@firediamond@addspecial{\oxidizer}\fi%
+ \ifKV@firediamond@asphixiant\nfpa@firediamond@addspecial{\asphixiant}\fi%
+ % Split commas. See
+ % http://www.tex.ac.uk/ctan/macros/latex/base/ltcntrl.dtx
+ % for details on LaTeX program control macros.
+ \@for\@ii:=\nfpa@firediamond@extraspecial\do{%
+ \nfpa@firediamond@xaddspecial{\@ii}}%
+}
+
+% Print the contents of the special quadrant.
+\newcommand{\nfpa@firediamond@special}{%
+ \ifnum\value{nfpa@firediamond@ispecial}>0%
+ \setcounter{nfpa@firediamond@jspecial}{1}%
+ \nfpa@firediamond@getspecial{nfpa@firediamond@jspecial}%
+ \fi%
+}
+
+% Print special contents to be printed below the special quadrant.
+\newcommand{\nfpa@firediamond@underspecial}{%
+ \begingroup%
+ \setlength{\parskip}{0pt}%
+ \setlength{\parindent}{0pt}%
+ \addtocounter{nfpa@firediamond@ispecial}{1}%
+ \forloop{nfpa@firediamond@jspecial}% counter
+ {2}% initial value
+ {\value{nfpa@firediamond@jspecial} < \value{nfpa@firediamond@ispecial}}% condition
+ {\nfpa@firediamond@getspecial{nfpa@firediamond@jspecial}\\}% code
+ \addtocounter{nfpa@firediamond@ispecial}{-1}%
+ \endgroup%
+}
+
+\newcommand{\firediamond}[1]{%
+ \setkeys{firediamond}{#1}%
+ \nfpa@firediamond@makespecial{}%
+ % Simple text output for debugging xkeyval parameter setup.
+ %Health: \nfpa@firediamond@health \\
+ %Flammability: \nfpa@firediamond@flammability \\
+ %Reactivity: \nfpa@firediamond@reactivity \\
+ %Special: \par\nfpa@firediamond@special\par
+ %
+ % Draw the NFPA diamond
+ \begin{tikzpicture}[x=\nfpa@firediamond@radius, y=\nfpa@firediamond@radius]
+ % draw the background colors
+ \fill[blue] (0,0) -- (-0.5,-0.5) -- (-1,0) -- (-0.5,0.5) -- cycle;
+ \fill[red] (0,0) -- (-0.5,0.5) -- (0,1) -- (0.5,0.5) -- cycle;
+ \fill[yellow] (0,0) -- (0.5,0.5) -- (1,0) -- (0.5,-0.5) -- cycle;
+ \fill[white] (0,0) -- (0.5,-0.5) -- (0,-1) -- (-0.5,-0.5) -- cycle;
+ %
+ % draw the borders
+ \draw (-0.5,-0.5) -- (0.5,0.5);
+ \draw (-0.5,0.5) -- (0.5,-0.5);
+ \draw (-1,0) -- (0,1) -- (1,0) -- (0,-1) -- cycle;
+ %
+ % add the text
+ \draw (-0.5,0) node { \nfpa@firediamond@health};
+ \draw (0,0.5) node { \nfpa@firediamond@flammability};
+ \draw (0.5,0) node { \nfpa@firediamond@reactivity};
+ \draw (0,-0.5) node[text width=\nfpa@firediamond@radius, text centered]
+ { \nfpa@firediamond@special};
+ \draw (0,-1) node[text width=\nfpa@firediamond@radius, text centered,
+ anchor=north]
+ { \nfpa@firediamond@underspecial};
+ \end{tikzpicture}
+}
--- /dev/null
+\documentclass{article}
+
+\usepackage{nfpa_704}
+
+\setlength{\parskip}{24pt}
+\setlength{\parindent}{12pt}
+
+\begin{document}
+\firediamond{health=5}
+
+\firediamond{reactivity=3, flammability=2, oxidizer}
+
+\firediamond{reactivity=3, flammability=2, oxidizer, nowater, asphixiant, special=CORR}
+
+% If you need multiple non-standard special warnings, they should be
+% separated with commas.
+\firediamond{health=2, nowater, asphixiant, special={CORR,BIO}}
+\end{document}
location regexp in the form below. For example: ".*liquids" or
"refrigerator".
</p>
-<form action="door_warning" method="post">
+<form action="door_warning.pdf" method="get">
<table>
<tr><td>Location regexp</td><td>:</td>
<td><input type="text" size="50" id="location" name="location"></td></tr>