last merge of edumed-red not complete
authorMarcin Koziej <marcin@koziej.info>
Wed, 30 Oct 2013 14:36:32 +0000 (15:36 +0100)
committerMarcin Koziej <marcin@koziej.info>
Wed, 30 Oct 2013 14:36:32 +0000 (15:36 +0100)
25 files changed:
librarian/__init__.py
librarian/book2anything.py
librarian/cover.py
librarian/fonts/Dosis-Bold.ttf [new file with mode: 0644]
librarian/fonts/Dosis-ExtraBold.ttf [new file with mode: 0644]
librarian/fonts/Dosis-ExtraLight.ttf [new file with mode: 0644]
librarian/fonts/Dosis-Light.ttf [new file with mode: 0644]
librarian/fonts/Dosis-Medium.ttf [new file with mode: 0644]
librarian/fonts/Dosis-Regular.ttf [new file with mode: 0644]
librarian/fonts/Dosis-SemiBold.ttf [new file with mode: 0644]
librarian/parser.py
librarian/pdf.py
librarian/pdf/wl.cls
librarian/pyhtml.py
librarian/pypdf.py
librarian/res/styles/edumed/logo.png [new file with mode: 0644]
librarian/res/styles/edumed/pdf/edumed.sty [new file with mode: 0755]
librarian/res/wasysym/uwasy.fd [new file with mode: 0644]
librarian/res/wasysym/uwasyvar.fd [new file with mode: 0644]
librarian/res/wasysym/wasysym.dtx [new file with mode: 0644]
librarian/res/wasysym/wasysym.ins [new file with mode: 0644]
librarian/res/wasysym/wasysym.sty [new file with mode: 0644]
librarian/styles/wolnelektury/cover.py
librarian/xmlutils.py
setup.py

index 430fb7e..23244ef 100644 (file)
@@ -79,8 +79,8 @@ class WLURI(object):
     """Represents a WL URI. Extracts slug from it."""
     slug = None
 
-    example = 'http://edukacjamedialna.edu.pl/'
-    _re_wl_uri = re.compile(r'http://(www\.)?edukacjamedialna.edu.pl/(lekcje/)?'
+    example = 'http://edukacjamedialna.edu.pl/lekcje/template'
+    _re_wl_uri = re.compile(r'http://(www\.)?edukacjamedialna.edu.pl/lekcje/'
             '(?P<slug>[-a-z0-9]+)/?$')
 
     def __init__(self, uri):
@@ -101,10 +101,10 @@ class WLURI(object):
         """Contructs an URI from slug.
 
         >>> WLURI.from_slug('a-slug').uri
-        u'http://wolnelektury.pl/katalog/lektura/a-slug/'
+        u'http://edukacjamedialna.edu.pl/lekcje/a-slug/'
 
         """
-        uri = 'http://prawokultury.pl/publikacje/%s/' % slug
+        uri = 'http://edukacjamedialna.edu.pl/lekcje/%s/' % slug
         return cls(uri)
 
     def __unicode__(self):
@@ -113,6 +113,9 @@ class WLURI(object):
     def __str__(self):
         return self.uri
 
+    def canonical(self):
+        return type(self).from_slug(self.slug)
+
     def __eq__(self, other):
         return self.slug == other.slug
 
index b8b8d27..b60cd0f 100755 (executable)
@@ -10,7 +10,6 @@ import optparse
 
 from librarian import DirDocProvider, ParseError
 from librarian.parser import WLDocument
-from librarian.cover import WLCover
 
 
 class Option(object):
@@ -88,7 +87,7 @@ class Book2Anything(object):
         for option in cls.parser_options:
             parser_args[option.name()] = option.value(options)
         # Prepare additional args for transform method.
-        transform_args = {}
+        transform_args = {"verbose": options.verbose}
         for option in cls.transform_options:
             transform_args[option.name()] = option.value(options)
         # Add flags to transform_args, if any.
@@ -98,6 +97,7 @@ class Book2Anything(object):
             transform_args['flags'] = transform_flags
         # Add cover support, if any.
         if cls.uses_cover:
+            from librarian.styles.wolnelektury.cover import WLCover
             if options.image_cache:
                 def cover_class(*args, **kwargs):
                     return WLCover(image_cache=options.image_cache, *args, **kwargs)
index 1db96cb..dc64a9c 100644 (file)
@@ -4,7 +4,7 @@
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 import re
-import Image, ImageFont, ImageDraw, ImageFilter
+from PIL import Image, ImageFont, ImageDraw, ImageFilter
 from StringIO import StringIO
 from librarian import get_resource, IOFile
 
diff --git a/librarian/fonts/Dosis-Bold.ttf b/librarian/fonts/Dosis-Bold.ttf
new file mode 100644 (file)
index 0000000..d5e938e
Binary files /dev/null and b/librarian/fonts/Dosis-Bold.ttf differ
diff --git a/librarian/fonts/Dosis-ExtraBold.ttf b/librarian/fonts/Dosis-ExtraBold.ttf
new file mode 100644 (file)
index 0000000..2144a25
Binary files /dev/null and b/librarian/fonts/Dosis-ExtraBold.ttf differ
diff --git a/librarian/fonts/Dosis-ExtraLight.ttf b/librarian/fonts/Dosis-ExtraLight.ttf
new file mode 100644 (file)
index 0000000..2e3bf1b
Binary files /dev/null and b/librarian/fonts/Dosis-ExtraLight.ttf differ
diff --git a/librarian/fonts/Dosis-Light.ttf b/librarian/fonts/Dosis-Light.ttf
new file mode 100644 (file)
index 0000000..a22e7d7
Binary files /dev/null and b/librarian/fonts/Dosis-Light.ttf differ
diff --git a/librarian/fonts/Dosis-Medium.ttf b/librarian/fonts/Dosis-Medium.ttf
new file mode 100644 (file)
index 0000000..3254ef5
Binary files /dev/null and b/librarian/fonts/Dosis-Medium.ttf differ
diff --git a/librarian/fonts/Dosis-Regular.ttf b/librarian/fonts/Dosis-Regular.ttf
new file mode 100644 (file)
index 0000000..4b20862
Binary files /dev/null and b/librarian/fonts/Dosis-Regular.ttf differ
diff --git a/librarian/fonts/Dosis-SemiBold.ttf b/librarian/fonts/Dosis-SemiBold.ttf
new file mode 100644 (file)
index 0000000..5f48caf
Binary files /dev/null and b/librarian/fonts/Dosis-SemiBold.ttf differ
index f02b64c..fb2f986 100644 (file)
@@ -204,8 +204,8 @@ class WLDocument(object):
         return epub.transform(self, *args, **kwargs)
 
     def as_pdf(self, *args, **kwargs):
-        from librarian import pdf
-        return pdf.transform(self, *args, **kwargs)
+        from librarian import pypdf
+        return pypdf.EduModulePDFFormat(self).build(*args, **kwargs)
 
     def as_mobi(self, *args, **kwargs):
         from librarian import mobi
@@ -217,7 +217,7 @@ class WLDocument(object):
 
     def as_cover(self, cover_class=None, *args, **kwargs):
         if cover_class is None:
-            from librarian.cover import WLCover
+            from librarian.styles.wolnelektury.cover import WLCover
             cover_class = WLCover
         return cover_class(self.book_info, *args, **kwargs).output_file()
 
index 9308704..03879fe 100644 (file)
@@ -175,7 +175,7 @@ def package_available(package, args='', verbose=False):
 
 def load_including_children(wldoc=None, provider=None, uri=None):
     """ Makes one big xml file with children inserted at end.
-    
+
     Either wldoc or provider and URI must be provided.
     """
 
@@ -203,7 +203,7 @@ def load_including_children(wldoc=None, provider=None, uri=None):
 
 class PDFFormat(Format):
     """ Base PDF format.
-    
+
     Available customization:
         nofootnotes: Doesn't do footnotes.
         nothemes: Doesn't do themes.
@@ -265,6 +265,9 @@ class PDFFormat(Format):
         # Copy style
         shutil.copy(get_resource('pdf/wl.cls'), temp)
         shutil.copy(self.style, os.path.join(temp, 'style.sty'))
+        #for sfile in ['wasysym.sty', 'uwasyvar.fd', 'uwasy.fd']:
+        #    shutil.copy(get_resource(os.path.join('res/wasysym', sfile)), temp)
+
         # Save attachments
         if self.cover:
             self.cover.for_pdf().dump_to(os.path.join(temp, 'makecover.sty'))
@@ -287,7 +290,7 @@ class PDFFormat(Format):
                 p = call(['xelatex', '-interaction=batchmode', tex_path],
                             stdout=PIPE, stderr=PIPE)
         if p:
-            raise ParseError("Error parsing .tex file")
+            raise ParseError("Error parsing .tex file: %s" % tex_path)
 
         if cwd is not None:
             os.chdir(cwd)
@@ -303,7 +306,7 @@ class PDFFormat(Format):
         """
         self.verbose = verbose
         self.save_tex = save_tex
-        
+
         if morefloats is None and package_available('morefloats', 'maxfloats=19'):
             morefloats = 'new'
         self.morefloats = morefloats
index 53da8d5..128a183 100755 (executable)
@@ -14,6 +14,7 @@
 
 \RequirePackage{setspace}
 \RequirePackage{type1cm}
+\RequirePackage{wasysym}
 \DeclareOption{13pt}{%
 \AtEndOfClass{%
 % font size definitions, similar to ones in /usr/share/texmf-texlive/tex/latex/base/
 \usepackage[overload]{textcase}
 \usepackage{scalefnt}
 % TODO: link color is a style thing
-\usepackage[colorlinks=true,linkcolor=black,setpagesize=false,urlcolor=black,xetex]{hyperref}
+\usepackage[hyphens]{url}
+\usepackage[colorlinks=true,linkcolor=black,setpagesize=false,urlcolor=blue,xetex]{hyperref}
 
 \ifenablewlfont
 \setmainfont [
 %ExternalLocation,
-UprightFont = JunicodeWL-Regular,
-ItalicFont = JunicodeWL-Italic,
-BoldFont = JunicodeWL-Regular,
-BoldItalicFont = JunicodeWL-Italic,
-SmallCapsFont = JunicodeWL-Regular,
+UprightFont = Dosis-Regular,
+ItalicFont = Dosis-SemiBold,
+BoldFont = Dosis-Bold,
+BoldItalicFont = Dosis-Bold,
+SmallCapsFont = Dosis-Regular,
 SmallCapsFeatures = {Letters={SmallCaps,UppercaseSmallCaps}},
 Numbers=OldStyle,
 Scale=1.04,
 LetterSpace=-1.0
-] {JunicodeWL}
+] {Dosis}
 
 \newfontfamily\alien[
 SmallCapsFeatures = {Letters={SmallCaps,UppercaseSmallCaps}},
@@ -148,7 +150,7 @@ Letters={SmallCaps,UppercaseSmallCaps}
 \fancyhf{}
 \renewcommand{\headrulewidth}{0pt}
 \renewcommand{\footrulewidth}{0pt}
-\lfoot{{\footnotesize \textsc{\@author} \emph{\@title}}}
+\lfoot{{\footnotesize \@author{} \emph{\@title}}}
 \cfoot{}
 \rfoot{{\footnotesize \thepage}}
 
@@ -170,7 +172,7 @@ Letters={SmallCaps,UppercaseSmallCaps}
 
 
 \newcommand{\typosubsubsection}[1]{%
-{\textsc{#1}}
+{#1}
 }
 
 \newcommand{\typosubsection}[1]{%
@@ -209,7 +211,7 @@ Letters={Uppercase}
 }
 
 \newcommand{\nazwautworu}[1]{%
-\section*{\typosection{#1}}%
+\section*{\raggedright{\typosection{#1}}}%
 }
 
 \newcommand{\podtytul}[1]{%
@@ -293,7 +295,7 @@ Letters={Uppercase}
 \subsubsection*{\typosubsubsection{#1}}%
 }
 \newcommand{\naglowekrozdzial}[1]{%
-\subsubsection*{\typosubsubsection{#1}}%
+{\subsubsection*{\raggedright{\typosubsubsection{#1}}}}%
 }
 
 \newcommand{\naglowekosoba}[1]{%
@@ -404,4 +406,3 @@ Letters={Uppercase}
 }%
 \fi
 }
-
index 775def1..68ae384 100644 (file)
@@ -82,7 +82,10 @@ class EduModule(Xmill):
             }
         submill = EduModule(dict(self.options.items() + {'sub_gen': True}.items()))
 
-        opis = submill.generate(element.xpath('opis')[0]) if len(element.xpath('opis')) else ""
+        if element.xpath('opis'):
+            opis = submill.generate(element.xpath('opis')[0])
+        else:
+            opis = ''
 
         n = element.xpath('wskazowki')
         if n: wskazowki = submill.generate(n[0])
@@ -196,7 +199,7 @@ u"""%(wskazowki)s
                     subgen = EduModule(self.options)
                     definiens_s = subgen.generate(definiens)
             else:
-                pass # print '!! Missing definiendum in source:', element.text
+                print '!! Missing definiendum in source:', element.text
 
         return u"<dt>", u"</dt>" + definiens_s
 
@@ -334,7 +337,7 @@ class Wybor(Exercise):
         if not pytania:
             pytania = [element]
         for p in pytania:
-            solutions = re.split(r"[, ]+", p.attrib.get('rozw', ''))
+            solutions = re.split(r"[, ]+", p.attrib['rozw'])
             if len(solutions) != 1:
                 is_single_choice = False
                 break
index cb082ca..9034753 100644 (file)
@@ -9,26 +9,20 @@ Creates one big XML from the book and its children, converts it to LaTeX
 with TeXML, then runs it by XeLaTeX.
 
 """
-from __future__ import with_statement
-import os
+from copy import deepcopy
 import os.path
 import shutil
-from StringIO import StringIO
-from tempfile import mkdtemp, NamedTemporaryFile
 import re
-from copy import deepcopy
-from subprocess import call, PIPE
+import random
+from urllib2 import urlopen
 
-from Texml.processor import process
 from lxml import etree
-from lxml.etree import XMLSyntaxError, XSLTApplyError
 
-from xmlutils import Xmill, tag, tagged, ifoption
+from xmlutils import Xmill, tag, tagged, ifoption, tag_open_close
 from librarian.dcparser import Person
-from librarian.parser import WLDocument
-from librarian import ParseError, DCNS, get_resource, IOFile, Format
+from librarian import DCNS, get_resource, IOFile
 from librarian import functions
-from pdf import PDFFormat
+from pdf import PDFFormat, substitute_hyphens, fix_hanging
 
 
 def escape(really):
@@ -48,15 +42,21 @@ def escape(really):
     return deco
 
 
-def cmd(name, pass_text=False):
-    def wrap(self, element):
-        pre = u'<cmd name="%s">' % name
+def cmd(name, parms=None):
+    def wrap(self, element=None):
+        pre, post = tag_open_close('cmd', name=name)
 
-        if pass_text:
-            pre += "<parm>%s</parm>" % element.text
-            return pre + '</cmd>'
+        if parms:
+            for parm in parms:
+                e = etree.Element("parm")
+                e.text = parm
+                pre += etree.tostring(e)
+        if element is not None:
+            pre += "<parm>"
+            post = "</parm>" + post
+            return pre, post
         else:
-            return pre, '</cmd>'
+            return pre + post
     return wrap
 
 
@@ -66,9 +66,17 @@ def mark_alien_characters(text):
 
 
 class EduModule(Xmill):
-    def __init__(self, options=None):
-        super(EduModule, self).__init__(options)
+    def __init__(self, options=None, state=None):
+        super(EduModule, self).__init__(options, state)
         self.activity_counter = 0
+        self.activity_last = None
+        self.exercise_counter = 0
+
+        def swap_endlines(txt):
+            if self.options['strofa']:
+                txt = txt.replace("/\n", '<ctrl ch="\\"/>')
+            return txt
+        self.register_text_filter(swap_endlines)
         self.register_text_filter(functions.substitute_entities)
         self.register_text_filter(mark_alien_characters)
 
@@ -91,11 +99,15 @@ class EduModule(Xmill):
           u'</cmd>'
 
     @escape(True)
-    def get_authors(self, element):
-        authors = self.get_dc(element, 'creator.expert') + \
-          self.get_dc(element, 'creator.scenario') + \
-          self.get_dc(element, 'creator.textbook')
-        return u', '.join(authors)
+    def get_authors(self, element, which=None):
+        dc = self.options['wldoc'].book_info
+        if which is None:
+            authors = dc.authors_textbook + \
+                dc.authors_scenario + \
+                dc.authors_expert
+        else:
+            authors = getattr(dc, "authors_%s" % which)
+        return u', '.join(author.readable() for author in authors)
 
     @escape(1)
     def get_title(self, element):
@@ -116,32 +128,99 @@ class EduModule(Xmill):
             \\usepackage{morefloats}
         }{}'''),
     u'''\\def\\authors{%s}''' % self.get_authors(element),
+    u'''\\def\\authorsexpert{%s}''' % self.get_authors(element, 'expert'),
+    u'''\\def\\authorsscenario{%s}''' % self.get_authors(element, 'scenario'),
+    u'''\\def\\authorstextbook{%s}''' % self.get_authors(element, 'textbook'),
+    
     u'''\\author{\\authors}''',
     u'''\\title{%s}''' % self.get_title(element),
-    u'''\\def\\bookurl{%s}''' % self.get_dc(element, 'identifier.url', True),
+    u'''\\def\\bookurl{%s}''' % self.options['wldoc'].book_info.url.canonical(),
     u'''\\def\\rightsinfo{%s}''' % self.get_rightsinfo(element),
     u'</TeXML>']
 
         return u"".join(filter(None, lines)), u'</TeXML>'
 
 
-    handle_naglowek_rozdzial = escape(True)(cmd("naglowekrozdzial", True))
-    handle_naglowek_podrozdzial = escape(True)(cmd("naglowekpodrozdzial", True))
-
     @escape(1)
     def handle_powiesc(self, element):
         return u"""
     <env name="document">
     <cmd name="maketitle"/>
-    """, """</env>"""
+    """, """<cmd name="editorialsection" /></env>"""
+
+    @escape(1)
+    def handle_texcommand(self, element):
+        cmd = functions.texcommand(element.tag)
+        return u'<TeXML escape="1"><cmd name="%s"><parm>' % cmd, u'</parm></cmd></TeXML>'
+
+    handle_akap = \
+    handle_akap = \
+    handle_akap_cd = \
+    handle_akap_cd = \
+    handle_akap_dialog = \
+    handle_akap_dialog = \
+    handle_autor_utworu = \
+    handle_dedykacja = \
+    handle_didaskalia = \
+    handle_didask_tekst = \
+    handle_dlugi_cytat = \
+    handle_dzielo_nadrzedne = \
+    handle_lista_osoba = \
+    handle_mat = \
+    handle_miejsce_czas = \
+    handle_motto = \
+    handle_motto_podpis = \
+    handle_naglowek_akt = \
+    handle_naglowek_czesc = \
+    handle_naglowek_listy = \
+    handle_naglowek_osoba = \
+    handle_naglowek_scena = \
+    handle_nazwa_utworu = \
+    handle_nota = \
+    handle_osoba = \
+    handle_pa = \
+    handle_pe = \
+    handle_podtytul = \
+    handle_poezja_cyt = \
+    handle_pr = \
+    handle_pt = \
+    handle_sekcja_asterysk = \
+    handle_sekcja_swiatlo = \
+    handle_separator_linia = \
+    handle_slowo_obce = \
+    handle_srodtytul = \
+    handle_tytul_dziela = \
+    handle_wyroznienie = \
+    handle_dywiz = \
+    handle_texcommand
+
+    def handle_naglowek_rozdzial(self, element):
+        if not self.options['teacher']:
+            if element.text.startswith((u'Wiedza', u'Zadania', u'Słowniczek')):
+                self.state['mute'] = False
+            else:
+                self.state['mute'] = True
+                return None
+        return self.handle_texcommand(element)
+    handle_naglowek_rozdzial.unmuter = True
+
+    def handle_naglowek_podrozdzial(self, element):
+        self.activity_counter = 0
+        return self.handle_texcommand(element)
+
+    def handle_uwaga(self, _e):
+        return None
+    def handle_extra(self, _e):
+        return None
+
+    def handle_nbsp(self, _e):
+        return '<spec cat="tilde" />'
 
-    handle_autor_utworu = cmd('autorutworu', True)
-    handle_nazwa_utworu = cmd('nazwautworu', True)
-    handle_dzielo_nadrzedne = cmd('dzielonadrzedne', True)
-    handle_podtytul = cmd('podtytul', True)
+    _handle_strofa = cmd("strofa")
 
-    handle_akap = handle_akap_dialog = handle_akap_cd = lambda s, e: ("\n", "\n")
-    handle_strofa = lambda s, e: ("\n","\n")
+    def handle_strofa(self, element):
+        self.options = {'strofa': True}
+        return self._handle_strofa(element)
 
     def handle_aktywnosc(self, element):
         self.activity_counter += 1
@@ -150,9 +229,12 @@ class EduModule(Xmill):
             'activity_counter': self.activity_counter,
             'sub_gen': True,
         }
-        submill = EduModule(self.options)
+        submill = EduModule(self.options, self.state)
 
-        opis = submill.generate(element.xpath('opis')[0])
+        if element.xpath('opis'):
+            opis = submill.generate(element.xpath('opis')[0])
+        else:
+            opis = ''
 
         n = element.xpath('wskazowki')
         if n: wskazowki = submill.generate(n[0])
@@ -169,12 +251,24 @@ class EduModule(Xmill):
 
         counter = self.activity_counter
 
+        if element.getnext().tag == 'aktywnosc' or self.activity_last.getnext() == element:
+            counter_tex = """<cmd name="activitycounter"><parm>%(counter)d.</parm></cmd>""" % locals()
+        else:
+            counter_tex = ''
+
+        self.activity_last = element
+
         return u"""
-Czas: %(czas)s min
-Forma: %(forma)s
-%(pomoce)s
+<cmd name="noindent" />
+%(counter_tex)s
+<cmd name="activityinfo"><parm>
+ <cmd name="activitytime"><parm>%(czas)s</parm></cmd>
+ <cmd name="activityform"><parm>%(forma)s</parm></cmd>
+ <cmd name="activitytools"><parm>%(pomoce)s</parm></cmd>
+</parm></cmd>
+
 
-%(counter)d. %(opis)s
+%(opis)s
 
 %(wskazowki)s
 """ % locals()
@@ -192,162 +286,358 @@ Forma: %(forma)s
     def handle_forma(self, *_):
         return
 
-#     def handle_cwiczenie(self, element):
-#         exercise_handlers = {
-#             'wybor': Wybor,
-#             'uporzadkuj': Uporzadkuj,
-#             'luki': Luki,
-#             'zastap': Zastap,
-#             'przyporzadkuj': Przyporzadkuj,
-#             'prawdafalsz': PrawdaFalsz
-#             }
-
-#         typ = element.attrib['typ']
-#         handler = exercise_handlers[typ](self.options)
-#         return handler.generate(element)
-
-#     # Lists
-#     def handle_lista(self, element, attrs={}):
-#         ltype = element.attrib.get('typ', 'punkt')
-#         if ltype == 'slowniczek':
-#             surl = element.attrib.get('href', None)
-#             sxml = None
-#             if surl:
-#                 sxml = etree.fromstring(self.options['provider'].by_uri(surl).get_string())
-#             self.options = {'slowniczek': True, 'slowniczek_xml': sxml }
-#             return '<div class="slowniczek">', '</div>'
-
-#         listtag = {'num': 'ol',
-#                'punkt': 'ul',
-#                'alfa': 'ul',
-#                'czytelnia': 'ul'}[ltype]
-
-#         classes = attrs.get('class', '')
-#         if classes: del attrs['class']
-
-#         attrs_s = ' '.join(['%s="%s"' % kv for kv in attrs.items()])
-#         if attrs_s: attrs_s = ' ' + attrs_s
-
-#         return '<%s class="lista %s %s"%s>' % (listtag, ltype, classes, attrs_s), '</%s>' % listtag
-
-#     def handle_punkt(self, element):
-#         if self.options['slowniczek']:
-#             return '<dl>', '</dl>'
-#         else:
-#             return '<li>', '</li>'
-
-#     def handle_definiendum(self, element):
-#         nxt = element.getnext()
-#         definiens_s = ''
-
-#         # let's pull definiens from another document
-#         if self.options['slowniczek_xml'] and (not nxt or nxt.tag != 'definiens'):
-#             sxml = self.options['slowniczek_xml']
-#             assert element.text != ''
-#             defloc = sxml.xpath("//definiendum[text()='%s']" % element.text)
-#             if defloc:
-#                 definiens = defloc[0].getnext()
-#                 if definiens.tag == 'definiens':
-#                     subgen = EduModule(self.options)
-#                     definiens_s = subgen.generate(definiens)
-
-#         return u"<dt>", u"</dt>" + definiens_s
-
-#     def handle_definiens(self, element):
-#         return u"<dd>", u"</dd>"
-
-
-#     def handle_podpis(self, element):
-#         return u"""<div class="caption">""", u"</div>"
-
-#     def handle_tabela(self, element):
-#         has_frames = int(element.attrib.get("ramki", "0"))
-#         if has_frames: frames_c = "framed"
-#         else: frames_c = ""
-#         return u"""<table class="%s">""" % frames_c, u"</table>"
-
-#     def handle_wiersz(self, element):
-#         return u"<tr>", u"</tr>"
-
-#     def handle_kol(self, element):
-#         return u"<td>", u"</td>"
-
-#     def handle_rdf__RDF(self, _):
-#         # ustal w opcjach  rzeczy :D
-#         return
-
-#     def handle_link(self, element):
-#         if 'material' in element.attrib:
-#             formats = re.split(r"[, ]+", element.attrib['format'])
-#             fmt_links = []
-#             for f in formats:
-#                 fmt_links.append(u'<a href="%s">%s</a>' % (self.options['urlmapper'].url_for_material(element.attrib['material'], f), f.upper()))
-
-#             return u"", u' (%s)' % u' '.join(fmt_links)
-
-
-# class Exercise(EduModule):
-#     def __init__(self, *args, **kw):
-#         self.question_counter = 0
-#         super(Exercise, self).__init__(*args, **kw)
-
-#     def handle_rozw_kom(self, element):
-#         return u"""<div style="display:none" class="comment">""", u"""</div>"""
-
-#     def handle_cwiczenie(self, element):
-#         self.options = {'exercise': element.attrib['typ']}
-#         self.question_counter = 0
-#         self.piece_counter = 0
-
-#         pre = u"""
-# <div class="exercise %(typ)s" data-type="%(typ)s">
-# <form action="#" method="POST">
-# """ % element.attrib
-#         post = u"""
-# <div class="buttons">
-# <span class="message"></span>
-# <input type="button" class="check" value="sprawdź"/>
-# <input type="button" class="retry" style="display:none" value="spróbuj ponownie"/>
-# <input type="button" class="solutions" value="pokaż rozwiązanie"/>
-# <input type="button" class="reset" value="reset"/>
-# </div>
-# </form>
-# </div>
-# """
-#         # Add a single <pytanie> tag if it's not there
-#         if not element.xpath(".//pytanie"):
-#             qpre, qpost = self.handle_pytanie(element)
-#             pre = pre + qpre
-#             post = qpost + post
-#         return pre, post
-
-#     def handle_pytanie(self, element):
-#         """This will handle <cwiczenie> element, when there is no <pytanie>
-#         """
-#         add_class = ""
-#         self.question_counter += 1
-#         self.piece_counter = 0
-#         solution = element.attrib.get('rozw', None)
-#         if solution: solution_s = ' data-solution="%s"' % solution
-#         else: solution_s = ''
-
-#         handles = element.attrib.get('uchwyty', None)
-#         if handles:
-#             add_class += ' handles handles-%s' % handles
-#             self.options = {'handles': handles}
-
-#         minimum = element.attrib.get('min', None)
-#         if minimum: minimum_s = ' data-minimum="%d"' % int(minimum)
-#         else: minimum_s = ''
-
-#         return '<div class="question%s" data-no="%d" %s>' %\
-#             (add_class, self.question_counter, solution_s + minimum_s), \
-#             "</div>"
+    def handle_lista(self, element, attrs={}):
+        ltype = element.attrib.get('typ', 'punkt')
+        if not element.findall("punkt"):
+            if ltype == 'czytelnia':
+                return 'W przygotowaniu.'
+            else:
+                return None
+        if ltype == 'slowniczek':
+            surl = element.attrib.get('src', None)
+            if surl is None:
+                # print '** missing src on <slowniczek>, setting default'
+                surl = 'http://edukacjamedialna.edu.pl/lekcje/slowniczek/'
+            sxml = None
+            if surl:
+                sxml = etree.fromstring(self.options['wldoc'].provider.by_uri(surl).get_string())
+            self.options = {'slowniczek': True, 'slowniczek_xml': sxml }
+
+        listcmd = {'num': 'enumerate',
+               'punkt': 'itemize',
+               'alfa': 'itemize',
+               'slowniczek': 'itemize',
+               'czytelnia': 'itemize'}[ltype]
+
+        return u'<env name="%s">' % listcmd, u'</env>'
+
+    def handle_punkt(self, element):
+        return '<cmd name="item"/>', ''
+
+    def handle_cwiczenie(self, element):
+        exercise_handlers = {
+            'wybor': Wybor,
+            'uporzadkuj': Uporzadkuj,
+            'luki': Luki,
+            'zastap': Zastap,
+            'przyporzadkuj': Przyporzadkuj,
+            'prawdafalsz': PrawdaFalsz
+        }
+
+        typ = element.attrib['typ']
+        self.exercise_counter += 1
+        if not typ in exercise_handlers:
+            return '(no handler)'
+        self.options = {'exercise_counter': self.exercise_counter}
+        handler = exercise_handlers[typ](self.options, self.state)
+        return handler.generate(element)
+
+    # XXX this is copied from pyhtml.py, except for return and
+    # should be refactored for no code duplication
+    def handle_definiendum(self, element):
+        nxt = element.getnext()
+        definiens_s = ''
+
+        # let's pull definiens from another document
+        if self.options['slowniczek_xml'] is not None and (nxt is None or nxt.tag != 'definiens'):
+            sxml = self.options['slowniczek_xml']
+            assert element.text != ''
+            defloc = sxml.xpath("//definiendum[text()='%s']" % element.text)
+            if defloc:
+                definiens = defloc[0].getnext()
+                if definiens.tag == 'definiens':
+                    subgen = EduModule(self.options, self.state)
+                    definiens_s = subgen.generate(definiens)
+
+        return u'<cmd name="textbf"><parm>', u"</parm></cmd>: " + definiens_s
+
+    def handle_definiens(self, element):
+        return u"", u""
+
+    def handle_podpis(self, element):
+        return u"""<env name="figure">""", u"</env>"
+
+    def handle_tabela(self, element):
+        max_col = 0
+        for w in element.xpath("wiersz"):
+            ks = w.xpath("kol")
+            if max_col < len(ks):
+                max_col = len(ks)
+        self.options = {'columnts': max_col}
+        # styling:
+                #        has_frames = int(element.attrib.get("ramki", "0"))
+                #        if has_frames: frames_c = "framed"
+                #        else: frames_c = ""
+                #        return u"""<table class="%s">""" % frames_c, u"</table>"
+        return u'''
+<cmd name="begin"><parm>tabular</parm><parm>%s</parm></cmd>
+    ''' % ('l' * max_col), \
+    u'''<cmd name="end"><parm>tabular</parm></cmd>'''
+
+    @escape(1)
+    def handle_wiersz(self, element):
+        return u"", u'<ctrl ch="\\"/>'
+
+    @escape(1)
+    def handle_kol(self, element):
+        if element.getnext() is not None:
+            return u"", u'<spec cat="align" />'
+        return u"", u""
+
+    def handle_link(self, element):
+        if element.attrib.get('url'):
+            url = element.attrib.get('url')
+            if url == element.text:
+                return cmd('url')(self, element)
+            else:
+                return cmd('href', parms=[element.attrib['url']])(self, element)
+        else:
+            return cmd('emph')(self, element)
+
+    def handle_obraz(self, element):
+        frmt = self.options['format']
+        name = element.attrib.get('nazwa', '').strip()
+        image = frmt.get_image(name.strip())
+        img_path = "obraz/%s" % name.replace("_", "")
+        frmt.attachments[img_path] = image
+        return cmd("obraz", parms=[img_path])(self)
+
+    def handle_video(self, element):
+        url = element.attrib.get('url')
+        if not url:
+            print '!! <video> missing url'
+            return
+        m = re.match(r'(?:https?://)?(?:www.)?youtube.com/watch\?(?:.*&)?v=([^&]+)(?:$|&)', url)
+        if not m:
+            print '!! unknown <video> url scheme:', url
+            return
+        name = m.group(1)
+        thumb = IOFile.from_string(urlopen
+            ("http://img.youtube.com/vi/%s/0.jpg" % name).read())
+        img_path = "video/%s.jpg" % name.replace("_", "")
+        self.options['format'].attachments[img_path] = thumb
+        canon_url = "https://www.youtube.com/watch?v=%s" % name
+        return cmd("video", parms=[img_path, canon_url])(self)
+
+
+class Exercise(EduModule):
+    def __init__(self, *args, **kw):
+        self.question_counter = 0
+        super(Exercise, self).__init__(*args, **kw)
+
+    handle_rozw_kom = ifoption(teacher=True)(cmd('akap'))
+
+    def handle_cwiczenie(self, element):
+        self.options = {
+            'exercise': element.attrib['typ'],
+            'sub_gen': True,
+        }
+        self.question_counter = 0
+        self.piece_counter = 0
+
+        header = etree.Element("parm")
+        header_cmd = etree.Element("cmd", name="naglowekpodrozdzial")
+        header_cmd.append(header)
+        header.text = u"Zadanie %d." % self.options['exercise_counter']
+
+        pre = etree.tostring(header_cmd, encoding=unicode)
+        post = u""
+        # Add a single <pytanie> tag if it's not there
+        if not element.xpath(".//pytanie"):
+            qpre, qpost = self.handle_pytanie(element)
+            pre = pre + qpre
+            post = qpost + post
+        return pre, post
+
+    def handle_pytanie(self, element):
+        """This will handle <cwiczenie> element, when there is no <pytanie>
+        """
+        self.question_counter += 1
+        self.piece_counter = 0
+        pre = post = u""
+        if self.options['teacher'] and element.attrib.get('rozw'):
+            post += u" [rozwiązanie: %s]" % element.attrib.get('rozw')
+        return pre, post
+
+    def handle_punkt(self, element):
+        pre, post = super(Exercise, self).handle_punkt(element)
+        if self.options['teacher'] and element.attrib.get('rozw'):
+            post += u" [rozwiązanie: %s]" % element.attrib.get('rozw')
+        return pre, post
+
+    def solution_header(self):
+        par = etree.Element("cmd", name="par")
+        parm = etree.Element("parm")
+        parm.text = u"Rozwiązanie:"
+        par.append(parm)
+        return etree.tostring(par)
+
+    def explicit_solution(self):
+        if self.options['solution']:
+            par = etree.Element("cmd", name="par")
+            parm = etree.Element("parm")
+            parm.text = self.options['solution']
+            par.append(parm)
+            return self.solution_header() + etree.tostring(par)
+
+
+
+class Wybor(Exercise):
+    def handle_cwiczenie(self, element):
+        pre, post = super(Wybor, self).handle_cwiczenie(element)
+        is_single_choice = True
+        pytania = element.xpath(".//pytanie")
+        if not pytania:
+            pytania = [element]
+        for p in pytania:
+            solutions = re.split(r"[, ]+", p.attrib.get('rozw', ''))
+            if len(solutions) != 1:
+                is_single_choice = False
+                break
+            choices = p.xpath(".//*[@nazwa]")
+            uniq = set()
+            for n in choices: uniq.add(n.attrib.get('nazwa', ''))
+            if len(choices) != len(uniq):
+                is_single_choice = False
+                break
+
+        self.options = {'single': is_single_choice}
+        return pre, post
+
+    def handle_punkt(self, element):
+        if self.options['exercise'] and element.attrib.get('nazwa', None):
+            cmd = 'radio' if self.options['single'] else 'checkbox'
+            return u'<cmd name="%s"/>' % cmd, ''
+        else:
+            return super(Wybor, self).handle_punkt(element)
+
+
+class Uporzadkuj(Exercise):
+    def handle_pytanie(self, element):
+        order_items = element.xpath(".//punkt/@rozw")
+        return super(Uporzadkuj, self).handle_pytanie(element)
+
+
+class Przyporzadkuj(Exercise):
+    def handle_lista(self, lista):
+        header = etree.Element("parm")
+        header_cmd = etree.Element("cmd", name="par")
+        header_cmd.append(header)
+        if 'nazwa' in lista.attrib:
+            header.text = u"Kategorie:"
+        elif 'cel' in lista.attrib:
+            header.text = u"Elementy do przyporządkowania:"
+        else:
+            header.text = u"Lista:"
+        pre, post = super(Przyporzadkuj, self).handle_lista(lista)
+        pre = etree.tostring(header_cmd, encoding=unicode) + pre
+        return pre, post
+
+
+class Luki(Exercise):
+    def find_pieces(self, question):
+        return question.xpath(".//luka")
+
+    def solution(self, piece):
+        piece = deepcopy(piece)
+        piece.tail = None
+        sub = EduModule()
+        return sub.generate(piece)
+
+    def handle_pytanie(self, element):
+        qpre, qpost = super(Luki, self).handle_pytanie(element)
+
+        luki = self.find_pieces(element)
+        random.shuffle(luki)
+        self.words = u"<env name='itemize'>%s</env>" % (
+            "".join("<cmd name='item'/>%s" % self.solution(luka) for luka in luki)
+        )
+        return qpre, qpost
+
+    def handle_opis(self, element):
+        return '', self.words
+
+    def handle_luka(self, element):
+        luka = "_" * 10
+        if self.options['teacher']:
+            piece = deepcopy(element)
+            piece.tail = None
+            sub = EduModule()
+            text = sub.generate(piece)
+            luka += u" [rozwiązanie: %s]" % text
+        return luka
+
+
+class Zastap(Luki):
+    def find_pieces(self, question):
+        return question.xpath(".//zastap")
+
+    def solution(self, piece):
+        return piece.attrib.get('rozw', '')
+
+    def list_header(self):
+        return u"Elementy do wstawienia"
+
+    def handle_zastap(self, element):
+        piece = deepcopy(element)
+        piece.tail = None
+        sub = EduModule()
+        text = sub.generate(piece)
+        if self.options['teacher'] and element.attrib.get('rozw'):
+            text += u" [rozwiązanie: %s]" % element.attrib.get('rozw')
+        return text
+
+
+class PrawdaFalsz(Exercise):
+    def handle_punkt(self, element):
+        pre, post = super(PrawdaFalsz, self).handle_punkt(element)
+        if 'rozw' in element.attrib:
+            post += u" [Prawda/Fałsz]"
+        return pre, post
+
+
+
+def fix_lists(tree):
+    lists = tree.xpath(".//lista")
+    for l in lists:
+        if l.text:
+            p = l.getprevious()
+            if p is not None:
+                if p.tail is None: p.tail = ''
+                p.tail += l.text
+            else:
+                p = l.getparent()
+                if p.text is None: p.text = ''
+                p.text += l.text
+            l.text = ''
+    return tree
+
 
 class EduModulePDFFormat(PDFFormat):
+    style = get_resource('res/styles/edumed/pdf/edumed.sty')
+
     def get_texml(self):
-        edumod = EduModule()
-        texml = edumod.generate(self.wldoc.edoc.getroot()).encode('utf-8')
+        substitute_hyphens(self.wldoc.edoc)
+        fix_hanging(self.wldoc.edoc)
+
+        self.attachments = {}
+        edumod = EduModule({
+            "wldoc": self.wldoc,
+            "format": self,
+            "teacher": self.customization.get('teacher'),
+        })
+        texml = edumod.generate(fix_lists(self.wldoc.edoc.getroot())).encode('utf-8')
 
         open("/tmp/texml.xml", "w").write(texml)
         return texml
+
+    def get_tex_dir(self):
+        temp = super(EduModulePDFFormat, self).get_tex_dir()
+        shutil.copy(get_resource('res/styles/edumed/logo.png'), temp)
+        for name, iofile in self.attachments.items():
+            iofile.save_as(os.path.join(temp, name))
+        return temp
+
+    def get_image(self, name):
+        return self.wldoc.source.attachments[name]
+
diff --git a/librarian/res/styles/edumed/logo.png b/librarian/res/styles/edumed/logo.png
new file mode 100644 (file)
index 0000000..eab7eed
Binary files /dev/null and b/librarian/res/styles/edumed/logo.png differ
diff --git a/librarian/res/styles/edumed/pdf/edumed.sty b/librarian/res/styles/edumed/pdf/edumed.sty
new file mode 100755 (executable)
index 0000000..b25a99d
--- /dev/null
@@ -0,0 +1,74 @@
+\usepackage[MeX]{polski}
+
+\newcommand{\activitycounter}[1]{\vspace{1em}\par{\huge{#1}}}
+
+\newcommand{\activityinfo}[1]{\begin{flushright}\parbox[t]{2in}{#1}\end{flushright}}
+\newcommand{\activitytime}[1]{Czas: #1 min \\}
+\newcommand{\activityform}[1]{Forma: #1 \\}
+\newcommand{\activitytools}[1]{#1 \\}
+
+\newcommand*\checkbox{\item[\Square]}
+\newcommand*\radio{\item[\Circle]}
+
+
+\renewcommand{\naglowekrozdzial}[1]{%
+\subsection*{\typosubsection{#1}}%
+}
+
+\renewcommand{\naglowekpodrozdzial}[1]{%
+\subsubsection*{\typosubsubsection{#1}}%
+}
+
+\newcommand{\obraz}[1]{
+\includegraphics[width=8cm]{#1}
+}
+
+\newcommand{\video}[2]{
+\includegraphics[width=8cm]{#1}\\
+\href{#2}{(Otwórz wideo w serwisie YouTube)}
+}
+
+\renewcommand{\maketitle}{
+    {
+    \thispagestyle{empty}
+    \footnotesize
+    \color{theme}
+
+    \noindent \begin{minipage}[t]{.35\textwidth}\vspace{0pt}
+        \href{http://edukacjamedialna.edu.pl}{\xbox{\includegraphics[width=\textwidth]{logo.png}}}
+    \end{minipage}
+
+    \vspace{.6em}
+    \color{black}
+    }
+}
+
+\newcommand{\rightsinfostr}[2][] {
+    \ifx&#1&%
+        #2
+    \else
+        Udostępniono na licencji \href{#1}{#2}.
+    \fi
+}
+
+\newcommand{\editorialsection}{
+  \begin{figure}[b!]
+  {
+    \footnotesize
+    \color{theme}
+    \noindent \rule{\linewidth}{0.4pt}
+
+Tekst: \authorstextbook, scenariusz: \authorsscenario, konsultacja merytoryczna: \authorsexpert.
+Materiał pochodzi z serwisu \href{http://edukacjamedialna.edu.pl}{edukacjamedialna.edu.pl} prowadzonego przez 
+\href{http://nowoczesnapolska.org.pl}{Fundację Nowoczesna Polska}.
+
+\vspace{.6em}
+\rightsinfo
+
+\vspace{.6em}
+Źródło: \href{\bookurl}{\bookurl}.
+
+    \color{black}
+  }
+  \end{figure}
+}
diff --git a/librarian/res/wasysym/uwasy.fd b/librarian/res/wasysym/uwasy.fd
new file mode 100644 (file)
index 0000000..3b0f531
--- /dev/null
@@ -0,0 +1,52 @@
+%%
+%% This is file `uwasy.fd',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% wasysym.dtx  (with options: `fd')
+%% 
+%% Copyright (C) 1994-2003 by Axel Kielhorn.  All rights reserved.
+%% For additional copyright information see further down in this file.
+%% 
+%% This file is to be used with the LaTeX2e system.
+%% ------------------------------------------------
+%% 
+%% This program can be redistributed and/or modified under the terms
+%% of the LaTeX Project Public License Distributed from CTAN
+%% archives in directory macros/latex/base/lppl.txt; either
+%% version 1 of the License, or any later version.
+%% 
+%% IMPORTANT NOTICE:
+%% 
+%% Error reports in case of UNCHANGED versions to
+%% Axel Kielhorn
+%% A.Kielhorn@web.de
+%% 
+%% \CharacterTable
+%%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+%%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+%%   Digits        \0\1\2\3\4\5\6\7\8\9
+%%   Exclamation   \!     Double quote  \"     Hash (number) \#
+%%   Dollar        \$     Percent       \%     Ampersand     \&
+%%   Acute accent  \'     Left paren    \(     Right paren   \)
+%%   Asterisk      \*     Plus          \+     Comma         \,
+%%   Minus         \-     Point         \.     Solidus       \/
+%%   Colon         \:     Semicolon     \;     Less than     \<
+%%   Equals        \=     Greater than  \>     Question mark \?
+%%   Commercial at \@     Left bracket  \[     Backslash     \\
+%%   Right bracket \]     Circumflex    \^     Underscore    \_
+%%   Grave accent  \`     Left brace    \{     Vertical bar  \|
+%%   Right brace   \}     Tilde         \~}
+\ProvidesFile{uwasy.fd}%
+             [2003/10/30 v2.0
+              Wasy-2 symbol font definitions]
+\DeclareFontFamily{U}{wasy}{}
+\DeclareFontShape{U}{wasy}{m}{n}{ <5> <6> <7> <8> <9> gen * wasy
+      <10> <10.95> <12> <14.4> <17.28> <20.74> <24.88>wasy10  }{}
+\DeclareFontShape{U}{wasy}{b}{n}{ <-10> sub * wasy/m/n
+ <10> <10.95> <12> <14.4> <17.28> <20.74> <24.88>wasyb10 }{}
+\DeclareFontShape{U}{wasy}{bx}{n}{ <-> sub * wasy/b/n}{}
+\endinput
+%%
+%% End of file `uwasy.fd'.
diff --git a/librarian/res/wasysym/uwasyvar.fd b/librarian/res/wasysym/uwasyvar.fd
new file mode 100644 (file)
index 0000000..e186585
--- /dev/null
@@ -0,0 +1,57 @@
+%%
+%% This is file `uwasyvar.fd',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% wasysym.dtx  (with options: `fdvar')
+%% 
+%% Copyright (C) 1994-2003 by Axel Kielhorn.  All rights reserved.
+%% For additional copyright information see further down in this file.
+%% 
+%% This file is to be used with the LaTeX2e system.
+%% ------------------------------------------------
+%% 
+%% This program can be redistributed and/or modified under the terms
+%% of the LaTeX Project Public License Distributed from CTAN
+%% archives in directory macros/latex/base/lppl.txt; either
+%% version 1 of the License, or any later version.
+%% 
+%% IMPORTANT NOTICE:
+%% 
+%% Error reports in case of UNCHANGED versions to
+%% Axel Kielhorn
+%% A.Kielhorn@web.de
+%% 
+%% \CharacterTable
+%%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+%%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+%%   Digits        \0\1\2\3\4\5\6\7\8\9
+%%   Exclamation   \!     Double quote  \"     Hash (number) \#
+%%   Dollar        \$     Percent       \%     Ampersand     \&
+%%   Acute accent  \'     Left paren    \(     Right paren   \)
+%%   Asterisk      \*     Plus          \+     Comma         \,
+%%   Minus         \-     Point         \.     Solidus       \/
+%%   Colon         \:     Semicolon     \;     Less than     \<
+%%   Equals        \=     Greater than  \>     Question mark \?
+%%   Commercial at \@     Left bracket  \[     Backslash     \\
+%%   Right bracket \]     Circumflex    \^     Underscore    \_
+%%   Grave accent  \`     Left brace    \{     Vertical bar  \|
+%%   Right brace   \}     Tilde         \~}
+\ProvidesFile{uwasy.fd}%
+             [2003/10/30 v2.0
+              Wasy-2 symbol font definitions]
+\DeclareFontFamily{U}{wasy}{}
+\DeclareFontShape{U}{wasy}{m}{n}{%
+<5-6> wasy5
+<6-7> wasy6
+<7-8> wasy7
+<8-9> wasy8
+<9-10> wasy9
+<10-> wasy10}{}
+\DeclareFontShape{U}{wasy}{b}{n}{ <-10> sub * wasy/m/n
+ <10-> wasyb10 }{}
+\DeclareFontShape{U}{wasy}{bx}{n}{ <-> sub * wasy/b/n}{}
+\endinput
+%%
+%% End of file `uwasyvar.fd'.
diff --git a/librarian/res/wasysym/wasysym.dtx b/librarian/res/wasysym/wasysym.dtx
new file mode 100644 (file)
index 0000000..f698cc1
--- /dev/null
@@ -0,0 +1,750 @@
+% \iffalse meta-comment
+%
+% Copyright  1994 - 99 by Axel Kielhorn
+% Copyright  2003 Axel Kielhorn, Walter Schmidt
+% 
+% This program can be redistributed and/or modified under the terms
+% of the LaTeX Project Public License Distributed from CTAN
+% archives in directory macros/latex/base/lppl.txt; either
+% version 1 of the License, or any later version.
+% 
+% IMPORTANT NOTICE:
+% 
+% For error reports in case of UNCHANGED versions contact
+% A.Kielhorn@web.de
+% 
+% You are not allowed to change this file.
+%
+% Changes:
+% 1.0b corrected mathcode for integrals (now 1)
+% 1.0c Minor corrections
+% 1.0e Resync with latex2e [1995/06/01]
+%      Changed some ops to \mathbin
+% 1.0f Corrected \dh and \Dh in T1 encoding as suggested by 
+%      Ernst-Guenter Giessmann (giessman@informatik.hu-berlin.de)
+% 1.0g Reintroduced \hbox in many commands, they work in math-mode
+%      again
+% 1.0h Included some changes by Donald Arseneau
+% 1.0i Changed License to LPPL
+% 1.0j Added uwasyvar.fd for scaleable PS fonts
+%      Added substitution bx -> b
+% 2.0  See the section "Changes over version~1.x".
+%      The instructions how to set up the font definition files
+%      for scaleable Type1 fonts have been moved to the 
+%      installation script, because they are needed at install
+%      time.
+%      \overstrike macro renamed to \wasy@over to avoid potential
+%       clashes
+% \fi
+%
+% \CheckSum{844}
+%% \CharacterTable
+%%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+%%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+%%   Digits        \0\1\2\3\4\5\6\7\8\9
+%%   Exclamation   \!     Double quote  \"     Hash (number) \#
+%%   Dollar        \$     Percent       \%     Ampersand     \&
+%%   Acute accent  \'     Left paren    \(     Right paren   \)
+%%   Asterisk      \*     Plus          \+     Comma         \,
+%%   Minus         \-     Point         \.     Solidus       \/
+%%   Colon         \:     Semicolon     \;     Less than     \<
+%%   Equals        \=     Greater than  \>     Question mark \?
+%%   Commercial at \@     Left bracket  \[     Backslash     \\
+%%   Right bracket \]     Circumflex    \^     Underscore    \_
+%%   Grave accent  \`     Left brace    \{     Vertical bar  \|
+%%   Right brace   \}     Tilde         \~}
+%
+% \iffalse   % this is a METACOMMENT !
+%
+%<package>\NeedsTeXFormat{LaTeX2e}
+%<package>\ProvidesPackage{wasysym}
+%<fd|fdvar>\ProvidesFile{uwasy.fd}%
+%<-driver>             [2003/10/30 v2.0
+%<package>               Wasy-2 symbol support package]
+%<fd|fdvar>              Wasy-2 symbol font definitions]
+%
+%
+%<*driver>
+\documentclass{ltxdoc}
+\OnlyDescription
+\usepackage[integrals]{wasysym}
+\providecommand\dst{\expandafter{\normalfont\scshape docstrip}}
+\renewcommand{\quad}{{\hskip1em plus 2em}}
+\begin{document}
+ \DocInput{wasysym.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \GetFileInfo{wasysym.sty}
+% \title{The \texttt{wasysym} macro package for \LaTeXe}
+% \author{Axel Kielhorn}
+% \date{version \fileversion{} -- \filedate}
+% \maketitle
+%
+% \setcounter{StandardModuleDepth}{1}
+%
+%
+% \section{Introduction}
+%
+%    This file defines the package |wasysym| which makes some
+%    additional characters available that come from the \texttt{wasy} fonts.
+%    These fonts were provided by Roland Waldi, Universit\"at Karlsruhe, 
+%    Germany.  
+%    Notice that the present macro package requires version~2 (1992) of 
+%    these fonts. It is not 100 \% compatible to the old 
+%    version~1 from 1989. I have provided no compatibility mode 
+%    for the old fonts! If some characters come out wrong or are
+%    missing, you have to upgrade.
+%
+%    Some of the symbols below are already provided in the T1 or TS1 
+%    (textcompanion) encodings, and |wasysm| serves only to make them 
+%    available also with the traditional (OT1-encoded) CM-Roman fonts. 
+%    Other symbols are  provided in the AMS symbol fonts, too, and can
+%    be accessed using either the |amssymb| or the |amsfonts| package.
+%
+% \section{The symbols}   
+%
+%   \subsection{Various math symbols}
+%    The following commands are valid in math mode only:
+%    \begin{quote}
+%    |\Join|~$\Join$ \quad
+%    |\Box|~$\Box$ \quad
+%    |\Diamond|~$\Diamond$ \quad
+%    |\leadsto|~$\leadsto$ \quad
+%    |\sqsubset|~$\sqsubset$ \quad
+%    |\sqsupset|~$\sqsupset$ \quad
+%    |\lhd|~$\lhd$ \quad
+%    |\unlhd|~$\unlhd$ \quad
+%    |\LHD|~$\LHD$\quad
+%    |\rhd|~$\rhd$ \quad
+%    |\unrhd|~$\unrhd$ \quad
+%    |\RHD|~$\RHD$\quad
+%    |\apprle|~$\apprle$\quad
+%    |\apprge|~$\apprge$\quad
+%    |\wasypropto|~$\wasypropto$\quad
+%    |\invneg|~$\invneg$\quad
+%    |\ocircle|~$\ocircle$\quad
+%    |\logof|~$\logof$\quad
+%    \end{quote}
+%
+%   \subsection{Integrals}
+%   The |wasy| fonts provide a set of integral sybols, which comprises
+%   multiple integrals and surface integrals, too.  
+%   \begin{itemize}
+%   \item
+%    Loading the package
+%    with the option \texttt{[integrals]} makes the following integrals available:
+%    \begin{quote}
+%    |\int|~$\int$\quad
+%    |\iint|~$\iint$\quad
+%    |\iiint|~$\iiint$\quad
+%    |\oint|~$\oint$\quad
+%    |\oiint|~$\oiint$
+%    \end{quote}
+%   Notice that the style of the |\int| and |\oint| is changed, as compared
+%   with standard \LaTeX, and matches the other integral symbols.
+%   This works with or without the |amsmath| package,  
+%   and the sequence of loading does not matter.
+%   \item
+%   If you prefer to stay with the integral symbols provided by \LaTeX
+%   (and possibly |amsmath|),
+%   but need other symbols from the \texttt{wasy} fonts,
+%   load the package with the option \texttt{[nointegrals]}.  Doing so will 
+%   neither alter any existing integral symbols nor add new ones.
+%   \item
+%   Loading the package \emph{without an option} or with the option \texttt{[compat1]}
+%   makes the following commands for integrals available:
+%    \begin{quote}
+%    |\varint|~$\int$\quad
+%    |\iint|~$\iint$\quad
+%    |\iiint|~$\iiint$\quad
+%    |\varoint|~$\oint$\quad
+%    |\oiint|~$\oiint$
+%    \end{quote}
+%   This is compatible with the behavior of |wasysym| version~1.x,
+%   but the package will not cooperate well with |amsmath| then.
+%   \end{itemize}
+%
+% \subsection{General symbols}
+%
+%    \begin{quote}
+%  |\male|~\male \quad
+%  |\female|~\female \quad
+%  |\currency|~\currency \quad
+%  |\phone|~\phone \quad
+%  |\recorder|~\recorder \quad
+%  |\clock|~\clock \quad
+%  |\lightning|~\lightning \quad
+%  |\pointer|~\pointer \quad
+%  |\RIGHTarrow|~\RIGHTarrow \quad
+%  |\LEFTarrow|~\LEFTarrow \quad
+%  |\UParrow|~\UParrow \quad
+%  |\DOWNarrow|~\DOWNarrow \quad
+%  |\diameter|~\diameter \quad
+%  |\invdiameter|~\invdiameter \quad
+%  |\varangle|~\varangle \quad
+%  |\wasylozenge|~\wasylozenge \quad
+%  |\kreuz|~\kreuz \quad
+%  |\smiley|~\smiley \quad
+%  |\frownie|~\frownie \quad
+%  |\blacksmiley|~\blacksmiley \quad
+%  |\sun|~\sun \quad
+%  |\checked|~\checked \quad
+%  |\bell|~\bell \quad
+%  |\ataribox|~\ataribox \quad
+%  |\cent|~\cent \quad
+%  |\permil|~\permil \quad
+%  |\brokenvert|~\brokenvert \quad
+%  |\wasytherefore|~\wasytherefore \quad
+%  |\Bowtie|~\Bowtie \quad
+%  |\agemO|~\agemO
+%   \end{quote}
+%
+%  \subsection{Electrical and physical symbols}
+%
+%   \begin{quote}
+%  |\AC|~\AC \quad
+%  |\HF|~\HF \quad
+%  |\VHF|~\VHF \quad
+%  |\photon|~\photon \quad
+%  |\gluon|~\gluon
+%   \end{quote}
+%
+%   \subsection{Polygons and stars}
+%
+%   \begin{quote}
+%  |\Square|~\Square \quad
+%  |\XBox|~\XBox \quad
+%  |\CheckedBox|~\CheckedBox \quad
+%  |\hexagon|~\hexagon \quad
+%  |\varhexagon|~\varhexagon \quad
+%  |\pentagon|~\pentagon \quad
+%  |\octagon|~\octagon \quad
+%  |\hexstar|~\hexstar \quad
+%  |\varhexstar|~\varhexstar \quad
+%  |\davidsstar|~\davidsstar
+%   \end{quote}
+%
+%   \subsection{Music notes}
+%
+%   \begin{quote}
+%  |\eighthnote|~\eighthnote \quad
+%  |\quarternote|~\quarternote \quad
+%  |\halfnote|~\halfnote \quad
+%  |\fullnote|~\fullnote \quad
+%  |\twonotes|~\twonotes
+%   \end{quote}
+%
+%  \subsection{Various circles}
+%
+%   \begin{quote}
+%  |\Circle|~\Circle \quad
+%  |\CIRCLE|~\CIRCLE \quad
+%  |\Leftcircle|~\Leftcircle \quad
+%  |\LEFTCIRCLE|~\LEFTCIRCLE \quad
+%  |\Rightcircle|~\Rightcircle \quad
+%  |\RIGHTCIRCLE|~\RIGHTCIRCLE \quad
+%  |\LEFTcircle|~\LEFTcircle \quad
+%  |\RIGHTcircle|~\RIGHTcircle \quad
+%  |\leftturn|~\leftturn \quad
+%  |\rightturn|~\rightturn \quad
+%   \end{quote}
+%
+%  \subsection{Phonetic symbols}
+%
+%   \begin{quote}
+%  |\dh|~{\fontencoding{OT1}\fontfamily{cmr}\selectfont\dh} \quad
+%  |\DH|~{\fontencoding{OT1}\fontfamily{cmr}\selectfont\DH} \quad 
+%  |\thorn|~\thorn \quad
+%  |\Thorn|~\Thorn \quad
+%  |\openo|~\openo \quad
+%  |\inve|~\inve
+%   \end{quote}
+%
+%   T1-encoded fonts normally include  Eth characters of their own.
+%   The |wasy| package tries to provide  them in the OT1 encoding, too.
+%   by ``faking'' them.
+%   This should work with the Computer Modern fonts, but may fail with others.
+%
+%   The characters produced by |\thorn|, |\Thorn|, |\openo| and |\inve|  
+%   match only the CM-Roman typeface
+%   and do not change with the surrounding font family or shape.
+%
+%  \subsection{Astronomical symbols}
+%
+%   \begin{quote}
+%  |\vernal|~\vernal \quad
+%  |\ascnode|~\ascnode \quad
+%  |\descnode|~\descnode \quad
+%  |\fullmoon|~\fullmoon \quad
+%  |\newmoon|~\newmoon \quad
+%  |\leftmoon|~\leftmoon \quad
+%  |\rightmoon|~\rightmoon \quad
+%  |\astrosun|~\astrosun \quad
+%  |\mercury|~\mercury \quad
+%  |\venus|~\venus \quad
+%  |\earth|~\earth \quad
+%  |\mars|~\mars \quad
+%  |\jupiter|~\jupiter \quad
+%  |\saturn|~\saturn \quad
+%  |\uranus|~\uranus \quad
+%  |\neptune|~\neptune \quad
+%  |\pluto|~\pluto
+%   \end{quote}
+%
+%   \subsection{Astrological symbols and the zodiacal symbols}
+%
+%    \begin{quote}
+%  |\aries|~\aries \quad
+%  |\taurus|~\taurus \quad
+%  |\gemini|~\gemini \quad
+%  |\cancer|~\cancer \quad
+%  |\leo|~\leo \quad
+%  |\virgo|~\virgo \quad
+%  |\libra|~\libra \quad
+%  |\scorpio|~\scorpio \quad
+%  |\sagittarius|~\sagittarius \quad
+%  |\capricornus|~\capricornus \quad
+%  |\aquarius|~\aquarius \quad
+%  |\pisces|~\pisces \quad
+%  |\conjunction|~\conjunction \quad
+%  |\opposition|~\opposition
+%   \end{quote}
+%
+%  \subsection{APL symbols}
+%
+%    \begin{quote}
+%  |\APLstar|~\APLstar \quad
+%  |\APLlog|~\APLlog \quad
+%  |\APLbox|~\APLbox \quad
+%  |\APLup|~\APLup \quad
+%  |\APLdown|~\APLdown \quad
+%  |\APLinput|~\APLinput \quad
+%  |\APLcomment|~\APLcomment \quad
+%  |\APLinv|~\APLinv \quad
+%  |\APLuparrowbox|~\APLuparrowbox \quad
+%  |\APLdownarrowbox|~\APLdownarrowbox \quad
+%  |\APLleftarrowbox|~\APLleftarrowbox \quad
+%  |\APLrightarrowbox|~\APLrightarrowbox \quad
+%  |\notbackslash|~\notbackslash \quad
+%  |\notslash|~\notslash \quad
+%  |\APLnot|~\APLnot\ \quad
+%  |\APLvert|~\APLvert\ \quad
+%  |\APLcirc|~\APLcirc\ \quad
+%  |\APLminus|~\APLminus
+%
+%    \end{quote}
+%
+% \section{Changes over version~1.x}
+% \begin{itemize}
+%   \item
+%    The |\Dh| command has finally been abolished.
+%    \item
+%    The macros 
+%    |\LEFTcircle|, |\RIGHTcircle|, |\CheckedBox| and |\APLinv|
+%    start with  |\leavevmode| now, so that they work properly at the 
+%    beginning of a paragraph.
+%    \item
+%    Use of the \texttt{wasy}-style integral symbols can be controlled 
+%    via the options \texttt{[compat1]}, \texttt{[integrals]} and \texttt{[nointegrals]},
+%    with \texttt{[compat1]} being the default.
+%    \item
+%    When loaded with the \texttt{[integrals]} or \texttt{[nointegrals]} option, 
+%    the package will not clash with |amsmath|.
+% \end{itemize}
+%
+%
+% \StopEventually{}
+%
+% \section{The \dst{} modules}
+%
+% The following modules are used in the implementation to direct
+% \dst{} in generating the external files:
+% \begin{center}
+% \begin{tabular}{ll}
+%   driver & produce a documentation driver file \\
+%   package  & produce a package file \\
+%   fd     & produce a font definition file \\
+%   fdvar    & produce a \texttt{.fd} file for use with scalable fonts
+% \end{tabular}
+% \end{center}
+%
+% \section{The Implementation}
+% \subsection{The macro package}
+%
+%  With the version 1.x of |wasysym|, the definitions of the multiple 
+%  integrals would depend on whether |amsmath| was loaded additionally, and whether it 
+%  was loaded before or after |wasysym|.  Redefinition of \emph{all} integrals
+%  so as to exhibit the same style was only possible through the (almost) undocumented 
+%  macros |\newint| and |\newamsint|.  Similar problems would also arise
+%  with the Fourier math fonts.
+%  This behavior was hard to understand and somewhat unfortunate\dots
+%
+%  Three options are now introduced to control the (re)definiton of the integral macros
+%  and a ``version~1 compatibility mode'':
+%    \begin{macrocode}
+%<*package>
+\newif\ifwasy@integrals
+\newif\ifwasy@compatibility
+\DeclareOption{compat1}{%
+  \wasy@compatibilitytrue\wasy@integralsfalse}%
+\DeclareOption{integrals}{%
+  \wasy@compatibilityfalse\wasy@integralstrue}%
+\DeclareOption{nointegrals}{%
+  \wasy@compatibilityfalse\wasy@integralsfalse}%
+\ExecuteOptions{compat1}
+\ProcessOptions\relax
+%    \end{macrocode}
+%  \begin{itemize}
+%  \item
+%  By default or with the option \texttt{[compat1]}, version~2 will behave just as version~1,
+%  i.e. the macros |\varint|, |\iint|, |\iiint|, |\varoint| and |\oiint| are defined at load time.
+%  \item
+%  With the option \texttt{[nointegrals]}, the meaning of any ``standard''
+%  or AMS integral macros remains unchanged, and the additional \texttt{wasy}
+%  integrals cannot be used.
+%  Thus, one can use the other \texttt{wasy} symbols without altering the 
+%  integral signs.
+%  \item
+%  With the option \texttt{[integrals]}, the standard
+%  and (if applicable) AMS integral macros are redefined to match the style of the
+%  additional \texttt{wasy} integrals.  The definitions are deferred until 
+%  |\begin{document}|, so that other package cannot interfere.
+%  The redefined integral macros will cooperate with the |amsmath| package,
+%  if it is loaded additionally.
+%  \item
+%  The undocumented commands |\newint| and |\newamsint|, too, may turn on
+%  the redefinition of the integral commands.
+%  \end{itemize}
+%
+%  The following two macros serve to actually (re)define the integrals.
+%  The first one  is to be used if the |amsmath| package is not loaded:
+%    \begin{macrocode}
+\def\wasy@setup{%
+     \let\int\wasy@int  
+     \let\iint\wasy@iint 
+     \let\iiint\wasy@iiint 
+     \let\oint\wasy@oint 
+     \let\oiint\wasy@oiint
+} 
+%    \end{macrocode}
+%    With |amsmath|, it's a bit more complicated:
+%    \begin{macrocode}
+\def\wasy@amssetup{%
+     \let\intop\wasy@int
+     \let\iintop\wasy@iint 
+     \let\iiintop\wasy@iiint
+     \let\ointop\wasy@oint  
+     \let\oiintop\wasy@oiint
+     \def\int{\DOTSI\intop\ilimits@}%
+     \def\iint{\DOTSI\iintop\ilimits@}%
+     \def\iiint{\DOTSI\iiintop\ilimits@}%
+     \def\oint{\DOTSI\ointop\ilimits@}%
+     \def\oiint{\DOTSI\oiintop\ilimits@}%
+     \def\intkern@{\mkern-8mu}
+}
+%    \end{macrocode}
+%
+% The old undocumented commands |\newint| and |\newamsint| are changed,
+% so as to effect the same  as the |integrals| option  and issue a warning
+% message:
+%    \begin{macrocode}
+\newcommand{\newint}{%
+  \PackageWarning{wasysym}{%
+  The command \protect\newint\space is obsolete.
+  \MessageBreak
+  Load the package with the option [integrals] instead}
+  \wasy@integralstrue}
+\newcommand{\newamsint}{%
+  \PackageWarning{wasysym}{%
+  The command \protect\newamsint\space is obsolete.
+  \MessageBreak
+  Load the package with the option [integrals] instead.}
+  \wasy@integralstrue}
+%    \end{macrocode}
+%
+%
+%    To access the wasy symbols in text mode I have defined them
+%    as a new fontfamily. Since I only take single characters but
+%    don't want to write long text this is not an elegant approach. 
+%    But it works and the symbols scale according to textsize, which 
+%    is all I promised.
+%    \begin{macrocode}
+\def\wasyfamily{\fontencoding{U}\fontfamily{wasy}\selectfont}
+\DeclareTextFontCommand{\textwasy}{\wasyfamily}
+%    \end{macrocode}
+%
+% We declare a \texttt{wasy} math symbol font, too:
+%    \begin{macrocode}
+\DeclareSymbolFont{wasy}{U}{wasy}{m}{n}
+\SetSymbolFont{wasy}{bold}{U}{wasy}{b}{n}
+%    \end{macrocode}
+%
+%    We declare a new command to generate overlayed symbols:
+%    \begin{macrocode}
+\def\wasy@over#1#2{{\setbox0\hbox{$#2$}\hbox to \wd0{\hss
+    $#1$\hss}\kern-\wd0\box0}}
+%    \end{macrocode}
+%
+%     Defining some special symbols:
+%    \begin{macrocode}
+\def\male       {\mbox{\wasyfamily\char26}}
+\def\female     {\mbox{\wasyfamily\char25}}
+\def\currency   {{\wasyfamily\char27}}
+\def\phone      {{\wasyfamily\char7}}
+\def\recorder   {{\wasyfamily\char6}}
+\def\clock      {{\wasyfamily\char28}}
+\def\lightning  {{\wasyfamily\char18}}
+\def\pointer    {{\wasyfamily\char9}}
+\def\RIGHTarrow {{\wasyfamily\char17}}
+\def\LEFTarrow  {{\wasyfamily\char16}}
+\def\UParrow    {{\wasyfamily\char75}}
+\def\DOWNarrow  {{\wasyfamily\char76}}
+\def\AC         {\mbox{\kern0.5pt\wasyfamily\char58\kern0.5pt}}
+\def\HF         {\leavevmode
+        \lower0.9pt\hbox to 0pt{\kern0.5pt\wasyfamily\char58\hss}%
+        \raise0.9pt\hbox{\kern0.5pt\wasyfamily\char58\kern0.5pt}}
+\def\VHF        {\mbox{\wasyfamily\char64}}
+\def\Square     {\mbox{$\Box$}}
+\def\CheckedBox {\leavevmode\hbox to 0pt{\wasyfamily\char50\hss}%
+                 \hbox{\wasyfamily\char8}}
+\def\XBox       {\mbox{\wasyfamily\char52}}
+\def\hexagon    {\mbox{\wasyfamily\char55}}
+\def\pentagon   {\mbox{\wasyfamily\char68}}
+\def\octagon    {\mbox{\wasyfamily\char56}}
+\def\varhexagon {\mbox{\wasyfamily\char57}}
+\def\hexstar    {\mbox{\wasyfamily\char65}}
+\def\varhexstar {\mbox{\wasyfamily\char66}}
+\def\davidsstar {\mbox{\wasyfamily\char67}}
+\def\diameter   {\mbox{\wasyfamily\char31}}
+\def\invdiameter{\mbox{\wasyfamily\char21}}
+\def\varangle   {\mbox{\wasyfamily\char30}}
+\def\wasylozenge{\mbox{\wasyfamily\char53}}
+\def\kreuz      {\mbox{\wasyfamily\char54}}
+\def\smiley     {\mbox{\wasyfamily\char44}}
+\def\frownie    {\mbox{\wasyfamily\char47}}
+\def\blacksmiley{\mbox{\wasyfamily\char45}}
+\def\sun        {\mbox{\wasyfamily\char46}}
+\def\checked    {\mbox{\wasyfamily\char8}}
+\def\bell       {\mbox{\wasyfamily\char10}}
+\def\eighthnote {\mbox{\wasyfamily\char11}}
+\def\quarternote{\mbox{\wasyfamily\char12}}
+\def\halfnote   {\mbox{\wasyfamily\char13}}
+\def\fullnote   {\mbox{\wasyfamily\char14}}
+\def\twonotes   {\mbox{\wasyfamily\char15}}
+\def\brokenvert {\mbox{\wasyfamily\char124}}
+\def\ataribox   {\mbox{\wasyfamily\char109}}
+\def\wasytherefore{\mbox{\wasyfamily\char5}}
+\def\Circle     {\mbox{\wasyfamily\char35}}
+\def\CIRCLE     {\mbox{\wasyfamily\char32}}
+\def\Leftcircle {\mbox{\wasyfamily\char73}}
+\def\LEFTCIRCLE {\mbox{\wasyfamily\char71}}
+\def\Rightcircle{\mbox{\wasyfamily\char74}}
+\def\RIGHTCIRCLE{\mbox{\wasyfamily\char72}}
+\def\LEFTcircle {\leavevmode%
+                 \hbox to 0pt{\wasyfamily\char71\hss}%
+                 \hbox{\wasyfamily\char35}}
+\def\RIGHTcircle{\leavevmode%
+                 \hbox to 0pt{\wasyfamily\char72\hss}%
+                 \hbox{\wasyfamily\char35}}
+%    \end{macrocode}
+%
+%     Astronomy:
+%    \begin{macrocode}
+\def\vernal     {\mbox{\wasyfamily\char23}}
+\def\ascnode    {\mbox{\wasyfamily\char19}}
+\def\descnode   {\mbox{\wasyfamily\char20}}
+\let\fullmoon   \Circle
+\let\newmoon    \CIRCLE
+\def\leftmoon   {\mbox{\wasyfamily\char36}}
+\def\rightmoon  {\mbox{\wasyfamily\char37}}
+\def\astrosun   {\mbox{$\odot$}}
+\def\mercury    {\mbox{\wasyfamily\char39}}
+\def\venus      {\leavevmode\raise0.2ex\hbox{\wasyfamily\char25}}
+\def\earth      {\leavevmode\lower0.3ex\hbox{\wasyfamily\char38}}
+\def\mars       {\leavevmode\lower0.2ex\hbox{\wasyfamily\char26}}
+\def\jupiter    {\mbox{\wasyfamily\char88}}
+\def\saturn     {\mbox{\wasyfamily\char89}}
+\def\uranus     {\mbox{\wasyfamily\char90}}
+\def\neptune    {\mbox{\wasyfamily\char91}}
+\def\pluto      {\mbox{\wasyfamily\char92}}
+%    \end{macrocode}
+%
+%     The zodiac:
+%    \begin{macrocode}
+\let\aries      \vernal
+\def\taurus     {\mbox{\wasyfamily\char93}}
+\def\gemini     {\mbox{\wasyfamily\char94}}
+\def\cancer     {\mbox{\wasyfamily\char95}}
+\let\leo        \ascnode
+\def\virgo      {\mbox{\wasyfamily\char96}}
+\def\libra      {\mbox{\wasyfamily\char97}}
+\def\scorpio    {\mbox{\wasyfamily\char98}}
+\def\sagittarius{\mbox{\wasyfamily\char99}}
+\def\capricornus{\mbox{\wasyfamily\char100}}
+\def\aquarius   {\mbox{\wasyfamily\char101}}
+\def\pisces     {\mbox{\wasyfamily\char102}}
+\def\conjunction{{\wasyfamily\char86}}
+\def\opposition {{\wasyfamily\char87}}
+%    \end{macrocode}
+%
+%     APL characters:
+%    \begin{macrocode}
+\def\APLstar    {\mbox{\wasyfamily\char69}}
+\def\APLlog     {\mbox{\wasyfamily\char22}}
+\def\APLbox     {\mbox{\wasyfamily\char126}}
+\def\APLup      {\mbox{\wasyfamily\char0}}
+\def\APLdown    {\mbox{\wasyfamily\char70}}
+\def\APLinput   {\mbox{\wasyfamily\char125}}
+\def\APLcomment {\mbox{\wasyfamily\char127}}
+\def\APLinv     {{\leavevmode\hbox to 0pt{$\div$\hss}\APLbox}}
+\def\APLuparrowbox{\mbox{\wasyfamily\char110}}
+\def\APLdownarrowbox{\mbox{\wasyfamily\char111}}
+\def\APLleftarrowbox{\mbox{\wasyfamily\char112}}
+\def\APLrightarrowbox{\mbox{\wasyfamily\char113}}
+\def\notbackslash{\wasy@over{\backslash}{-}}
+\def\notslash   {\wasy@over{/}{-}}
+\def\APLminus   {\leavevmode\raise0.7ex\hbox{$-$}}
+\def\APLnot#1{\wasy@over{\sim}{#1}}
+\def\APLcirc#1{\wasy@over{\circ}{#1}}
+\def\APLvert#1{\wasy@over{\vert}{#1}}
+%    \end{macrocode}
+%
+%     Math symbols:
+%    \begin{macrocode}
+\def\Bowtie     {\mbox{\wasyfamily\char49}}
+\def\leftturn   {\mbox{\wasyfamily\char34}}
+\def\rightturn  {\mbox{\wasyfamily\char33}}
+%    \end{macrocode}
+%
+%     Particle physics:
+%    \begin{macrocode}
+\def\photon     {\mbox{\wasyfamily\char58\char58\char58\char58}}
+\def\gluon      {\mbox{\wasyfamily\char81\char80\char80\char80%
+    \char80\char80\char80\char82}}
+%    \end{macrocode}
+%
+%     Miscellaneous:
+%    \begin{macrocode}
+\def\cent       {\mbox{\wasyfamily\char103}}
+\def\permil     {\mbox{\wasyfamily\char104}}
+\def\agemO      {{\wasyfamily\char48}}
+%    \end{macrocode}
+%
+%     Phonetic:
+%    \begin{macrocode}
+\def\thorn      {{\wasyfamily\char105}}
+\def\Thorn      {{\wasyfamily\char106}}
+\DeclareTextCommand{\dh}{OT1}{{\wasyfamily\char107}}
+\DeclareTextCommand{\DH}{OT1}{\leavevmode{\rm\setbox0\hbox{D}%
+    \hbox to\wd0{\kern 0.04em\char32\hss D}}}
+\def\openo      {{\wasyfamily\char108}}
+\def\inve       {{\wasyfamily\char85}}
+%    \end{macrocode}
+%
+%
+%    Because the lasy symbols are made an error in the format we have
+%    to undefine them before we can set them anew with
+%    |\DeclareMathSymbol|. Made the mathgroups more readable and
+%    changed |\lhd| and friends to be binary operators as in
+%    latexsym.
+%    \begin{macrocode}
+  \let\mho\undefined
+  \let\sqsupset\undefined \let\Join\undefined
+  \let\lhd\undefined      \let\Box\undefined
+  \let\unlhd\undefined    \let\Diamond\undefined
+  \let\rhd\undefined      \let\leadsto\undefined
+  \let\unrhd\undefined    \let\sqsubset\undefined
+  \DeclareMathSymbol\mho     {\mathord}{wasy}{"30}
+  \DeclareMathSymbol\Join    {\mathrel}{wasy}{"31}
+  \DeclareMathSymbol\Box     {\mathord}{wasy}{"32}
+  \DeclareMathSymbol\Diamond {\mathord}{wasy}{"33}
+  \DeclareMathSymbol\leadsto {\mathrel}{wasy}{"3B}
+  \DeclareMathSymbol\sqsubset{\mathrel}{wasy}{"3C}
+  \DeclareMathSymbol\sqsupset{\mathrel}{wasy}{"3D}
+  \DeclareMathSymbol\lhd     {\mathbin}{wasy}{"01}
+  \DeclareMathSymbol\unlhd   {\mathbin}{wasy}{"02}
+  \DeclareMathSymbol\LHD     {\mathbin}{wasy}{"10}
+  \DeclareMathSymbol\rhd     {\mathbin}{wasy}{"03}
+  \DeclareMathSymbol\unrhd   {\mathbin}{wasy}{"04}
+  \DeclareMathSymbol\RHD     {\mathbin}{wasy}{"11}
+  \DeclareMathSymbol\apprle  {\mathrel}{wasy}{"3E}
+  \DeclareMathSymbol\apprge  {\mathrel}{wasy}{"3F}
+  \DeclareMathSymbol\wasypropto   {\mathrel}{wasy}{"1D}
+  \DeclareMathSymbol\invneg  {\mathrel}{wasy}{"18}
+  \DeclareMathSymbol\ocircle {\mathbin}{wasy}{"23}
+  \DeclareMathSymbol\logof   {\mathrel}{wasy}{"16}
+%    \end{macrocode}
+%    
+%    Initially the integrals are defined with ``harmless''
+%    names. i.e., no existing macros are overwritten:
+%    \begin{macrocode}
+  \DeclareMathSymbol\wasy@int  {\mathop}{wasy}{"72}
+  \DeclareMathSymbol\wasy@iint {\mathop}{wasy}{"73}
+  \DeclareMathSymbol\wasy@iiint{\mathop}{wasy}{"74}
+  \DeclareMathSymbol\wasy@oint {\mathop}{wasy}{"75}
+  \DeclareMathSymbol\wasy@oiint{\mathop}{wasy}{"76}
+%    \end{macrocode}
+%
+% Now let's actually set up the integrals.  
+% In ``compatibility mode'' they are defined immediately at load time:
+%    \begin{macrocode}
+\ifwasy@compatibility
+  \let\varint\wasy@int
+  \let\iint\wasy@iint 
+  \let\iiint\wasy@iiint 
+  \let\varoint\wasy@oint
+  \let\oiint\wasy@oiint
+\fi
+%    \end{macrocode}
+% If the option \texttt{[integrals]} was selected, the related definitions
+% are executed only at |\begin{document}|.  Notice that the commands
+% |\newint| or |\newamsint| may appear in the preamble and turn on the
+% the redefinition of the integral macros.
+%    \begin{macrocode}
+\AtBeginDocument{%
+  \ifwasy@integrals
+    \@ifpackageloaded{amsmath}{\wasy@amssetup}{\wasy@setup}
+  \fi
+}
+%</package>
+%    \end{macrocode}
+%
+%  \subsection{The font definition files}
+%
+%    The declarations, 
+%    that have to go into the corresponding |.fd| files:
+%    \begin{macrocode}
+%<*fd>
+\DeclareFontFamily{U}{wasy}{}
+\DeclareFontShape{U}{wasy}{m}{n}{ <5> <6> <7> <8> <9> gen * wasy
+      <10> <10.95> <12> <14.4> <17.28> <20.74> <24.88>wasy10  }{}
+\DeclareFontShape{U}{wasy}{b}{n}{ <-10> sub * wasy/m/n
+ <10> <10.95> <12> <14.4> <17.28> <20.74> <24.88>wasyb10 }{}
+\DeclareFontShape{U}{wasy}{bx}{n}{ <-> sub * wasy/b/n}{}
+%</fd>
+%<*fdvar>
+\DeclareFontFamily{U}{wasy}{}
+\DeclareFontShape{U}{wasy}{m}{n}{%
+<5-6> wasy5
+<6-7> wasy6
+<7-8> wasy7
+<8-9> wasy8
+<9-10> wasy9
+<10-> wasy10}{}
+\DeclareFontShape{U}{wasy}{b}{n}{ <-10> sub * wasy/m/n
+ <10-> wasyb10 }{}
+\DeclareFontShape{U}{wasy}{bx}{n}{ <-> sub * wasy/b/n}{}
+%</fdvar>
+%    \end{macrocode}
+%
+%    The next line goes into all files and in addition prevents \dst{}
+%    from adding any further code from the main source file (such as a
+%    character table).
+%    \begin{macrocode}
+\endinput
+%    \end{macrocode}
+%
+% \DeleteShortVerb{\|}
+% \Finale
diff --git a/librarian/res/wasysym/wasysym.ins b/librarian/res/wasysym/wasysym.ins
new file mode 100644 (file)
index 0000000..0d2c5b5
--- /dev/null
@@ -0,0 +1,82 @@
+%%
+%% This file will generate fast loadable files and documentation
+%% driver files from the doc files in this package when run through
+%% LaTeX or TeX.
+%%
+%% 
+% Copyright  1994 - 2003 by Axel Kielhorn
+% 
+% This program can be redistributed and/or modified under the terms
+% of the LaTeX Project Public License Distributed from CTAN
+% archives in directory macros/latex/base/lppl.txt; either
+% version 1 of the License, or any later version.
+%
+%% --------------- start of docstrip commands ------------------
+%%
+\def\batchfile{wasysym.ins}
+\input docstrip.tex
+\preamble
+
+Copyright (C) 1994-2003 by Axel Kielhorn.  All rights reserved.
+For additional copyright information see further down in this file.
+
+This file is to be used with the LaTeX2e system.
+------------------------------------------------
+
+This program can be redistributed and/or modified under the terms
+of the LaTeX Project Public License Distributed from CTAN
+archives in directory macros/latex/base/lppl.txt; either
+version 1 of the License, or any later version.
+
+IMPORTANT NOTICE:
+
+Error reports in case of UNCHANGED versions to
+Axel Kielhorn
+A.Kielhorn@web.de
+
+\endpreamble
+\def\batchfile{wasysym.dst}   % ignored in distribution
+\input docstrip.tex            % ignored in distribution
+
+\keepsilent
+
+\Msg{*** Generating .sty files ***}
+
+\generateFile{wasysym.sty}{t}{%
+  \from{wasysym.dtx}{package}}
+
+
+\Msg{*** Generating .fd files ***}
+
+\generateFile{uwasy.fd}{t}{
+     \from{wasysym.dtx}{fd}}
+\generateFile{uwasyvar.fd}{t}{
+     \from{wasysym.dtx}{fdvar}}
+
+
+\ifToplevel{
+\Msg{***********************************************************}
+\Msg{*}
+\Msg{* To finish the installation you have to move the following}
+\Msg{* files into a directory searched by TeX:}
+\Msg{*}
+\Msg{* \space\space wasysym.sty}
+\Msg{* \space\space uwasy.fd}
+\Msg{* \space\space uwasyvar.fd}
+\Msg{*}
+\Msg{* If you want to use the wasy symbols at arbitrary sizes}
+\Msg{* and have access to the scalable Type 1 fonts,}
+\Msg{* substitute the font definition file uwasyvar.fd for}
+\Msg{* uwasy.fd, i.e. rename uwasyvar.fd to uwasy.fd.}
+\Msg{* Doing so is, however, not recommended, if you have}
+\Msg{* got bitmap fonts only.}
+\Msg{*}
+\Msg{* To produce the documentation run the files ending with}
+\Msg{* `.dtx' through LaTeX.}
+\Msg{*}
+\Msg{* Happy TeXing}
+\Msg{***********************************************************}
+}
+
+\endinput
+
diff --git a/librarian/res/wasysym/wasysym.sty b/librarian/res/wasysym/wasysym.sty
new file mode 100644 (file)
index 0000000..742cc9c
--- /dev/null
@@ -0,0 +1,261 @@
+%%
+%% This is file `wasysym.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% wasysym.dtx  (with options: `package')
+%% 
+%% Copyright (C) 1994-2003 by Axel Kielhorn.  All rights reserved.
+%% For additional copyright information see further down in this file.
+%% 
+%% This file is to be used with the LaTeX2e system.
+%% ------------------------------------------------
+%% 
+%% This program can be redistributed and/or modified under the terms
+%% of the LaTeX Project Public License Distributed from CTAN
+%% archives in directory macros/latex/base/lppl.txt; either
+%% version 1 of the License, or any later version.
+%% 
+%% IMPORTANT NOTICE:
+%% 
+%% Error reports in case of UNCHANGED versions to
+%% Axel Kielhorn
+%% A.Kielhorn@web.de
+%% 
+%% \CharacterTable
+%%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+%%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+%%   Digits        \0\1\2\3\4\5\6\7\8\9
+%%   Exclamation   \!     Double quote  \"     Hash (number) \#
+%%   Dollar        \$     Percent       \%     Ampersand     \&
+%%   Acute accent  \'     Left paren    \(     Right paren   \)
+%%   Asterisk      \*     Plus          \+     Comma         \,
+%%   Minus         \-     Point         \.     Solidus       \/
+%%   Colon         \:     Semicolon     \;     Less than     \<
+%%   Equals        \=     Greater than  \>     Question mark \?
+%%   Commercial at \@     Left bracket  \[     Backslash     \\
+%%   Right bracket \]     Circumflex    \^     Underscore    \_
+%%   Grave accent  \`     Left brace    \{     Vertical bar  \|
+%%   Right brace   \}     Tilde         \~}
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{wasysym}
+             [2003/10/30 v2.0
+               Wasy-2 symbol support package]
+\newif\ifwasy@integrals
+\newif\ifwasy@compatibility
+\DeclareOption{compat1}{%
+  \wasy@compatibilitytrue\wasy@integralsfalse}%
+\DeclareOption{integrals}{%
+  \wasy@compatibilityfalse\wasy@integralstrue}%
+\DeclareOption{nointegrals}{%
+  \wasy@compatibilityfalse\wasy@integralsfalse}%
+\ExecuteOptions{compat1}
+\ProcessOptions\relax
+\def\wasy@setup{%
+     \let\int\wasy@int
+     \let\iint\wasy@iint
+     \let\iiint\wasy@iiint
+     \let\oint\wasy@oint
+     \let\oiint\wasy@oiint
+}
+\def\wasy@amssetup{%
+     \let\intop\wasy@int
+     \let\iintop\wasy@iint
+     \let\iiintop\wasy@iiint
+     \let\ointop\wasy@oint
+     \let\oiintop\wasy@oiint
+     \def\int{\DOTSI\intop\ilimits@}%
+     \def\iint{\DOTSI\iintop\ilimits@}%
+     \def\iiint{\DOTSI\iiintop\ilimits@}%
+     \def\oint{\DOTSI\ointop\ilimits@}%
+     \def\oiint{\DOTSI\oiintop\ilimits@}%
+     \def\intkern@{\mkern-8mu}
+}
+\newcommand{\newint}{%
+  \PackageWarning{wasysym}{%
+  The command \protect\newint\space is obsolete.
+  \MessageBreak
+  Load the package with the option [integrals] instead}
+  \wasy@integralstrue}
+\newcommand{\newamsint}{%
+  \PackageWarning{wasysym}{%
+  The command \protect\newamsint\space is obsolete.
+  \MessageBreak
+  Load the package with the option [integrals] instead.}
+  \wasy@integralstrue}
+\def\wasyfamily{\fontencoding{U}\fontfamily{wasy}\selectfont}
+\DeclareTextFontCommand{\textwasy}{\wasyfamily}
+\DeclareSymbolFont{wasy}{U}{wasy}{m}{n}
+\SetSymbolFont{wasy}{bold}{U}{wasy}{b}{n}
+\def\wasy@over#1#2{{\setbox0\hbox{$#2$}\hbox to \wd0{\hss
+    $#1$\hss}\kern-\wd0\box0}}
+\def\male       {\mbox{\wasyfamily\char26}}
+\def\female     {\mbox{\wasyfamily\char25}}
+\def\currency   {{\wasyfamily\char27}}
+\def\phone      {{\wasyfamily\char7}}
+\def\recorder   {{\wasyfamily\char6}}
+\def\clock      {{\wasyfamily\char28}}
+\def\lightning  {{\wasyfamily\char18}}
+\def\pointer    {{\wasyfamily\char9}}
+\def\RIGHTarrow {{\wasyfamily\char17}}
+\def\LEFTarrow  {{\wasyfamily\char16}}
+\def\UParrow    {{\wasyfamily\char75}}
+\def\DOWNarrow  {{\wasyfamily\char76}}
+\def\AC         {\mbox{\kern0.5pt\wasyfamily\char58\kern0.5pt}}
+\def\HF         {\leavevmode
+        \lower0.9pt\hbox to 0pt{\kern0.5pt\wasyfamily\char58\hss}%
+        \raise0.9pt\hbox{\kern0.5pt\wasyfamily\char58\kern0.5pt}}
+\def\VHF        {\mbox{\wasyfamily\char64}}
+\def\Square     {\mbox{$\Box$}}
+\def\CheckedBox {\leavevmode\hbox to 0pt{\wasyfamily\char50\hss}%
+                 \hbox{\wasyfamily\char8}}
+\def\XBox       {\mbox{\wasyfamily\char52}}
+\def\hexagon    {\mbox{\wasyfamily\char55}}
+\def\pentagon   {\mbox{\wasyfamily\char68}}
+\def\octagon    {\mbox{\wasyfamily\char56}}
+\def\varhexagon {\mbox{\wasyfamily\char57}}
+\def\hexstar    {\mbox{\wasyfamily\char65}}
+\def\varhexstar {\mbox{\wasyfamily\char66}}
+\def\davidsstar {\mbox{\wasyfamily\char67}}
+\def\diameter   {\mbox{\wasyfamily\char31}}
+\def\invdiameter{\mbox{\wasyfamily\char21}}
+\def\varangle   {\mbox{\wasyfamily\char30}}
+\def\wasylozenge{\mbox{\wasyfamily\char53}}
+\def\kreuz      {\mbox{\wasyfamily\char54}}
+\def\smiley     {\mbox{\wasyfamily\char44}}
+\def\frownie    {\mbox{\wasyfamily\char47}}
+\def\blacksmiley{\mbox{\wasyfamily\char45}}
+\def\sun        {\mbox{\wasyfamily\char46}}
+\def\checked    {\mbox{\wasyfamily\char8}}
+\def\bell       {\mbox{\wasyfamily\char10}}
+\def\eighthnote {\mbox{\wasyfamily\char11}}
+\def\quarternote{\mbox{\wasyfamily\char12}}
+\def\halfnote   {\mbox{\wasyfamily\char13}}
+\def\fullnote   {\mbox{\wasyfamily\char14}}
+\def\twonotes   {\mbox{\wasyfamily\char15}}
+\def\brokenvert {\mbox{\wasyfamily\char124}}
+\def\ataribox   {\mbox{\wasyfamily\char109}}
+\def\wasytherefore{\mbox{\wasyfamily\char5}}
+\def\Circle     {\mbox{\wasyfamily\char35}}
+\def\CIRCLE     {\mbox{\wasyfamily\char32}}
+\def\Leftcircle {\mbox{\wasyfamily\char73}}
+\def\LEFTCIRCLE {\mbox{\wasyfamily\char71}}
+\def\Rightcircle{\mbox{\wasyfamily\char74}}
+\def\RIGHTCIRCLE{\mbox{\wasyfamily\char72}}
+\def\LEFTcircle {\leavevmode%
+                 \hbox to 0pt{\wasyfamily\char71\hss}%
+                 \hbox{\wasyfamily\char35}}
+\def\RIGHTcircle{\leavevmode%
+                 \hbox to 0pt{\wasyfamily\char72\hss}%
+                 \hbox{\wasyfamily\char35}}
+\def\vernal     {\mbox{\wasyfamily\char23}}
+\def\ascnode    {\mbox{\wasyfamily\char19}}
+\def\descnode   {\mbox{\wasyfamily\char20}}
+\let\fullmoon   \Circle
+\let\newmoon    \CIRCLE
+\def\leftmoon   {\mbox{\wasyfamily\char36}}
+\def\rightmoon  {\mbox{\wasyfamily\char37}}
+\def\astrosun   {\mbox{$\odot$}}
+\def\mercury    {\mbox{\wasyfamily\char39}}
+\def\venus      {\leavevmode\raise0.2ex\hbox{\wasyfamily\char25}}
+\def\earth      {\leavevmode\lower0.3ex\hbox{\wasyfamily\char38}}
+\def\mars       {\leavevmode\lower0.2ex\hbox{\wasyfamily\char26}}
+\def\jupiter    {\mbox{\wasyfamily\char88}}
+\def\saturn     {\mbox{\wasyfamily\char89}}
+\def\uranus     {\mbox{\wasyfamily\char90}}
+\def\neptune    {\mbox{\wasyfamily\char91}}
+\def\pluto      {\mbox{\wasyfamily\char92}}
+\let\aries      \vernal
+\def\taurus     {\mbox{\wasyfamily\char93}}
+\def\gemini     {\mbox{\wasyfamily\char94}}
+\def\cancer     {\mbox{\wasyfamily\char95}}
+\let\leo        \ascnode
+\def\virgo      {\mbox{\wasyfamily\char96}}
+\def\libra      {\mbox{\wasyfamily\char97}}
+\def\scorpio    {\mbox{\wasyfamily\char98}}
+\def\sagittarius{\mbox{\wasyfamily\char99}}
+\def\capricornus{\mbox{\wasyfamily\char100}}
+\def\aquarius   {\mbox{\wasyfamily\char101}}
+\def\pisces     {\mbox{\wasyfamily\char102}}
+\def\conjunction{{\wasyfamily\char86}}
+\def\opposition {{\wasyfamily\char87}}
+\def\APLstar    {\mbox{\wasyfamily\char69}}
+\def\APLlog     {\mbox{\wasyfamily\char22}}
+\def\APLbox     {\mbox{\wasyfamily\char126}}
+\def\APLup      {\mbox{\wasyfamily\char0}}
+\def\APLdown    {\mbox{\wasyfamily\char70}}
+\def\APLinput   {\mbox{\wasyfamily\char125}}
+\def\APLcomment {\mbox{\wasyfamily\char127}}
+\def\APLinv     {{\leavevmode\hbox to 0pt{$\div$\hss}\APLbox}}
+\def\APLuparrowbox{\mbox{\wasyfamily\char110}}
+\def\APLdownarrowbox{\mbox{\wasyfamily\char111}}
+\def\APLleftarrowbox{\mbox{\wasyfamily\char112}}
+\def\APLrightarrowbox{\mbox{\wasyfamily\char113}}
+\def\notbackslash{\wasy@over{\backslash}{-}}
+\def\notslash   {\wasy@over{/}{-}}
+\def\APLminus   {\leavevmode\raise0.7ex\hbox{$-$}}
+\def\APLnot#1{\wasy@over{\sim}{#1}}
+\def\APLcirc#1{\wasy@over{\circ}{#1}}
+\def\APLvert#1{\wasy@over{\vert}{#1}}
+\def\Bowtie     {\mbox{\wasyfamily\char49}}
+\def\leftturn   {\mbox{\wasyfamily\char34}}
+\def\rightturn  {\mbox{\wasyfamily\char33}}
+\def\photon     {\mbox{\wasyfamily\char58\char58\char58\char58}}
+\def\gluon      {\mbox{\wasyfamily\char81\char80\char80\char80%
+    \char80\char80\char80\char82}}
+\def\cent       {\mbox{\wasyfamily\char103}}
+\def\permil     {\mbox{\wasyfamily\char104}}
+\def\agemO      {{\wasyfamily\char48}}
+\def\thorn      {{\wasyfamily\char105}}
+\def\Thorn      {{\wasyfamily\char106}}
+\DeclareTextCommand{\dh}{OT1}{{\wasyfamily\char107}}
+\DeclareTextCommand{\DH}{OT1}{\leavevmode{\rm\setbox0\hbox{D}%
+    \hbox to\wd0{\kern 0.04em\char32\hss D}}}
+\def\openo      {{\wasyfamily\char108}}
+\def\inve       {{\wasyfamily\char85}}
+  \let\mho\undefined
+  \let\sqsupset\undefined \let\Join\undefined
+  \let\lhd\undefined      \let\Box\undefined
+  \let\unlhd\undefined    \let\Diamond\undefined
+  \let\rhd\undefined      \let\leadsto\undefined
+  \let\unrhd\undefined    \let\sqsubset\undefined
+  \DeclareMathSymbol\mho     {\mathord}{wasy}{"30}
+  \DeclareMathSymbol\Join    {\mathrel}{wasy}{"31}
+  \DeclareMathSymbol\Box     {\mathord}{wasy}{"32}
+  \DeclareMathSymbol\Diamond {\mathord}{wasy}{"33}
+  \DeclareMathSymbol\leadsto {\mathrel}{wasy}{"3B}
+  \DeclareMathSymbol\sqsubset{\mathrel}{wasy}{"3C}
+  \DeclareMathSymbol\sqsupset{\mathrel}{wasy}{"3D}
+  \DeclareMathSymbol\lhd     {\mathbin}{wasy}{"01}
+  \DeclareMathSymbol\unlhd   {\mathbin}{wasy}{"02}
+  \DeclareMathSymbol\LHD     {\mathbin}{wasy}{"10}
+  \DeclareMathSymbol\rhd     {\mathbin}{wasy}{"03}
+  \DeclareMathSymbol\unrhd   {\mathbin}{wasy}{"04}
+  \DeclareMathSymbol\RHD     {\mathbin}{wasy}{"11}
+  \DeclareMathSymbol\apprle  {\mathrel}{wasy}{"3E}
+  \DeclareMathSymbol\apprge  {\mathrel}{wasy}{"3F}
+  \DeclareMathSymbol\wasypropto   {\mathrel}{wasy}{"1D}
+  \DeclareMathSymbol\invneg  {\mathrel}{wasy}{"18}
+  \DeclareMathSymbol\ocircle {\mathbin}{wasy}{"23}
+  \DeclareMathSymbol\logof   {\mathrel}{wasy}{"16}
+  \DeclareMathSymbol\wasy@int  {\mathop}{wasy}{"72}
+  \DeclareMathSymbol\wasy@iint {\mathop}{wasy}{"73}
+  \DeclareMathSymbol\wasy@iiint{\mathop}{wasy}{"74}
+  \DeclareMathSymbol\wasy@oint {\mathop}{wasy}{"75}
+  \DeclareMathSymbol\wasy@oiint{\mathop}{wasy}{"76}
+\ifwasy@compatibility
+  \let\varint\wasy@int
+  \let\iint\wasy@iint
+  \let\iiint\wasy@iiint
+  \let\varoint\wasy@oint
+  \let\oiint\wasy@oiint
+\fi
+\AtBeginDocument{%
+  \ifwasy@integrals
+    \@ifpackageloaded{amsmath}{\wasy@amssetup}{\wasy@setup}
+  \fi
+}
+\endinput
+%%
+%% End of file `wasysym.sty'.
index b417216..8181890 100644 (file)
@@ -3,7 +3,7 @@
 # This file is part of Librarian, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
-import Image, ImageFont, ImageDraw
+from PIL import Image, ImageFont, ImageDraw
 from StringIO import StringIO
 from librarian import get_resource, URLOpener
 from librarian.cover import Cover, TextBox
index 340ee83..bbcc884 100644 (file)
@@ -12,21 +12,35 @@ class Xmill(object):
     Used instead of XSLT which is difficult and cumbersome.
 
     """
-    def __init__(self, options=None):
+    def __init__(self, options=None, state=None):
         self._options = []
+        self.state = state or {}
         if options:
             self._options.append(options)
         self.text_filters = []
+        self.escaped_text_filters = []
 
     def register_text_filter(self, fun):
         self.text_filters.append(fun)
 
+    def register_escaped_text_filter(self, fun):
+        self.escaped_text_filters.append(fun)
+
     def filter_text(self, text):
         for flt in self.text_filters:
             if text is None:
                 return None
-            text = flt(text)
-        return text
+            else:
+                text = flt(text)
+        # TODO: just work on the tree and let lxml handle escaping.
+        e = etree.Element("x")
+        e.text = text
+        # This whole mixing text with ML is so wrong.
+        output = etree.tostring(e, encoding=unicode)[3:-4]
+        for flt in self.escaped_text_filters:
+            output = flt(output)
+        return output
+
 
     def generate(self, document):
         """Generate text from node using handlers defined in class."""
@@ -90,6 +104,7 @@ class Xmill(object):
         if isinstance(element, etree._Comment): return None
         
         handler = self._handle_for_element(element)
+        if self.state.get('mute') and not getattr(handler, 'unmuter', False): return None
         # How many scopes
         try:
             options_scopes = len(self._options)
@@ -114,6 +129,7 @@ class Xmill(object):
         finally:
             # clean up option scopes if necessary
             self._options = self._options[0:options_scopes]
+            
         return out
 
 
index a5f105d..0a3682f 100755 (executable)
--- a/setup.py
+++ b/setup.py
@@ -28,7 +28,12 @@ setup(
     maintainer='Radek Czajka',
     maintainer_email='radoslaw.czajka@nowoczesnapolska.org.pl',
     url='http://github.com/fnp/librarian',
-    packages=['librarian'],
+    packages=[
+        'librarian',
+        'librarian.styles',
+        'librarian.styles.wolnelektury',
+        'librarian.styles.wolnelektury.partners',
+    ],
     package_data={'librarian': ['xslt/*.xslt', 'epub/*', 'mobi/*', 'pdf/*', 'fb2/*', 'fonts/*'] +
                                 whole_tree(os.path.join(os.path.dirname(__file__), 'librarian'), 'font-optimizer') +
                                 whole_tree(os.path.join(os.path.dirname(__file__), 'librarian'), 'res')},