LilyPond-Ruby 0.0.2.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/etc/fonts/conf.d/10-hinting-slight.conf +15 -0
- data/etc/fonts/conf.d/10-scale-bitmap-fonts.conf +83 -0
- data/etc/fonts/conf.d/11-lcdfilter-default.conf +17 -0
- data/etc/fonts/conf.d/20-unhint-small-vera.conf +49 -0
- data/etc/fonts/conf.d/30-metric-aliases.conf +637 -0
- data/etc/fonts/conf.d/40-nonlatin.conf +332 -0
- data/etc/fonts/conf.d/45-generic.conf +136 -0
- data/etc/fonts/conf.d/45-latin.conf +301 -0
- data/etc/fonts/conf.d/48-spacing.conf +16 -0
- data/etc/fonts/conf.d/49-sansserif.conf +22 -0
- data/etc/fonts/conf.d/50-user.conf +16 -0
- data/etc/fonts/conf.d/51-local.conf +7 -0
- data/etc/fonts/conf.d/60-generic.conf +64 -0
- data/etc/fonts/conf.d/60-latin.conf +88 -0
- data/etc/fonts/conf.d/65-fonts-persian.conf +418 -0
- data/etc/fonts/conf.d/65-nonlatin.conf +228 -0
- data/etc/fonts/conf.d/69-unifont.conf +28 -0
- data/etc/fonts/conf.d/80-delicious.conf +19 -0
- data/etc/fonts/conf.d/90-synthetic.conf +64 -0
- data/etc/fonts/conf.d/README +23 -0
- data/etc/fonts/fonts.conf +101 -0
- data/etc/relocate/fontconfig.reloc +2 -0
- data/etc/relocate/guile.reloc +2 -0
- data/etc/relocate/libexec.reloc +1 -0
- data/lib/guile/2.2/ccache/ice-9/and-let-star.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/arrays.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/atomic.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/binary-ports.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/boot-9.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/buffered-input.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/calling.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/channel.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/command-line.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/common-list.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/control.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/curried-definitions.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/debug.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/deprecated.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/documentation.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/eval-string.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/eval.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/expect.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/fdes-finalizers.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/format.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/ftw.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/futures.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/gap-buffer.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/getopt-long.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/hash-table.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/hcons.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/history.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/i18n.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/iconv.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/lineio.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/list.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/local-eval.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/ls.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/mapping.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/match.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/networking.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/null.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/occam-channel.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/optargs.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/peg/cache.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/peg/codegen.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/peg/simplify-tree.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/peg/string-peg.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/peg/using-parsers.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/peg.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/poe.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/poll.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/popen.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/ports.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/posix.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/pretty-print.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/psyntax-pp.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/q.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/r5rs.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/rdelim.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/receive.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/regex.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/runq.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/rw.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/safe-r5rs.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/safe.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/sandbox.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/save-stack.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/scm-style-repl.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/serialize.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/session.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/slib.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/stack-catch.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/streams.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/string-fun.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/suspendable-ports.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/syncase.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/textual-ports.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/threads.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/time.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/top-repl.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/unicode.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/vlist.go +0 -0
- data/lib/guile/2.2/ccache/ice-9/weak-vector.go +0 -0
- data/lib/guile/2.2/ccache/language/brainfuck/compile-scheme.go +0 -0
- data/lib/guile/2.2/ccache/language/brainfuck/compile-tree-il.go +0 -0
- data/lib/guile/2.2/ccache/language/brainfuck/parse.go +0 -0
- data/lib/guile/2.2/ccache/language/brainfuck/spec.go +0 -0
- data/lib/guile/2.2/ccache/language/bytecode/spec.go +0 -0
- data/lib/guile/2.2/ccache/language/bytecode.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/closure-conversion.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/compile-bytecode.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/constructors.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/contification.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/cse.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/dce.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/effects-analysis.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/elide-values.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/handle-interrupts.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/intmap.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/intset.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/licm.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/optimize.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/peel-loops.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/primitives.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/prune-bailouts.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/prune-top-level-scopes.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/reify-primitives.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/renumber.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/rotate-loops.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/self-references.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/simplify.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/slot-allocation.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/spec.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/specialize-numbers.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/specialize-primcalls.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/split-rec.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/type-checks.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/type-fold.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/types.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/utils.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/verify.go +0 -0
- data/lib/guile/2.2/ccache/language/cps/with-cps.go +0 -0
- data/lib/guile/2.2/ccache/language/cps.go +0 -0
- data/lib/guile/2.2/ccache/language/ecmascript/array.go +0 -0
- data/lib/guile/2.2/ccache/language/ecmascript/base.go +0 -0
- data/lib/guile/2.2/ccache/language/ecmascript/compile-tree-il.go +0 -0
- data/lib/guile/2.2/ccache/language/ecmascript/function.go +0 -0
- data/lib/guile/2.2/ccache/language/ecmascript/impl.go +0 -0
- data/lib/guile/2.2/ccache/language/ecmascript/parse.go +0 -0
- data/lib/guile/2.2/ccache/language/ecmascript/spec.go +0 -0
- data/lib/guile/2.2/ccache/language/ecmascript/tokenize.go +0 -0
- data/lib/guile/2.2/ccache/language/elisp/bindings.go +0 -0
- data/lib/guile/2.2/ccache/language/elisp/boot.go +0 -0
- data/lib/guile/2.2/ccache/language/elisp/compile-tree-il.go +0 -0
- data/lib/guile/2.2/ccache/language/elisp/falias.go +0 -0
- data/lib/guile/2.2/ccache/language/elisp/lexer.go +0 -0
- data/lib/guile/2.2/ccache/language/elisp/parser.go +0 -0
- data/lib/guile/2.2/ccache/language/elisp/runtime/function-slot.go +0 -0
- data/lib/guile/2.2/ccache/language/elisp/runtime/value-slot.go +0 -0
- data/lib/guile/2.2/ccache/language/elisp/runtime.go +0 -0
- data/lib/guile/2.2/ccache/language/elisp/spec.go +0 -0
- data/lib/guile/2.2/ccache/language/scheme/compile-tree-il.go +0 -0
- data/lib/guile/2.2/ccache/language/scheme/decompile-tree-il.go +0 -0
- data/lib/guile/2.2/ccache/language/scheme/spec.go +0 -0
- data/lib/guile/2.2/ccache/language/tree-il/analyze.go +0 -0
- data/lib/guile/2.2/ccache/language/tree-il/canonicalize.go +0 -0
- data/lib/guile/2.2/ccache/language/tree-il/compile-cps.go +0 -0
- data/lib/guile/2.2/ccache/language/tree-il/debug.go +0 -0
- data/lib/guile/2.2/ccache/language/tree-il/effects.go +0 -0
- data/lib/guile/2.2/ccache/language/tree-il/fix-letrec.go +0 -0
- data/lib/guile/2.2/ccache/language/tree-il/optimize.go +0 -0
- data/lib/guile/2.2/ccache/language/tree-il/peval.go +0 -0
- data/lib/guile/2.2/ccache/language/tree-il/primitives.go +0 -0
- data/lib/guile/2.2/ccache/language/tree-il/spec.go +0 -0
- data/lib/guile/2.2/ccache/language/tree-il.go +0 -0
- data/lib/guile/2.2/ccache/language/value/spec.go +0 -0
- data/lib/guile/2.2/ccache/oop/goops/accessors.go +0 -0
- data/lib/guile/2.2/ccache/oop/goops/active-slot.go +0 -0
- data/lib/guile/2.2/ccache/oop/goops/composite-slot.go +0 -0
- data/lib/guile/2.2/ccache/oop/goops/describe.go +0 -0
- data/lib/guile/2.2/ccache/oop/goops/internal.go +0 -0
- data/lib/guile/2.2/ccache/oop/goops/save.go +0 -0
- data/lib/guile/2.2/ccache/oop/goops/simple.go +0 -0
- data/lib/guile/2.2/ccache/oop/goops/stklos.go +0 -0
- data/lib/guile/2.2/ccache/oop/goops.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/arithmetic/bitwise.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/arithmetic/fixnums.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/arithmetic/flonums.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/base.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/bytevectors.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/conditions.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/control.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/enums.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/eval.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/exceptions.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/files.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/hashtables.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/io/ports.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/io/simple.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/lists.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/mutable-pairs.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/mutable-strings.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/programs.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/r5rs.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/records/inspection.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/records/procedural.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/records/syntactic.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/sorting.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/syntax-case.go +0 -0
- data/lib/guile/2.2/ccache/rnrs/unicode.go +0 -0
- data/lib/guile/2.2/ccache/rnrs.go +0 -0
- data/lib/guile/2.2/ccache/scripts/api-diff.go +0 -0
- data/lib/guile/2.2/ccache/scripts/autofrisk.go +0 -0
- data/lib/guile/2.2/ccache/scripts/compile.go +0 -0
- data/lib/guile/2.2/ccache/scripts/disassemble.go +0 -0
- data/lib/guile/2.2/ccache/scripts/display-commentary.go +0 -0
- data/lib/guile/2.2/ccache/scripts/doc-snarf.go +0 -0
- data/lib/guile/2.2/ccache/scripts/frisk.go +0 -0
- data/lib/guile/2.2/ccache/scripts/generate-autoload.go +0 -0
- data/lib/guile/2.2/ccache/scripts/help.go +0 -0
- data/lib/guile/2.2/ccache/scripts/lint.go +0 -0
- data/lib/guile/2.2/ccache/scripts/list.go +0 -0
- data/lib/guile/2.2/ccache/scripts/punify.go +0 -0
- data/lib/guile/2.2/ccache/scripts/read-rfc822.go +0 -0
- data/lib/guile/2.2/ccache/scripts/read-scheme-source.go +0 -0
- data/lib/guile/2.2/ccache/scripts/read-text-outline.go +0 -0
- data/lib/guile/2.2/ccache/scripts/scan-api.go +0 -0
- data/lib/guile/2.2/ccache/scripts/snarf-check-and-output-texi.go +0 -0
- data/lib/guile/2.2/ccache/scripts/snarf-guile-m4-docs.go +0 -0
- data/lib/guile/2.2/ccache/scripts/summarize-guile-TODO.go +0 -0
- data/lib/guile/2.2/ccache/scripts/use2dot.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-1.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-10.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-11.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-111.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-13.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-14.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-16.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-17.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-18.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-19.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-2.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-26.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-27.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-28.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-31.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-34.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-35.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-37.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-38.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-39.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-4/gnu.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-4.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-41.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-42.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-43.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-45.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-6.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-60.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-64.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-67.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-69.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-71.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-8.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-88.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-9/gnu.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-9.go +0 -0
- data/lib/guile/2.2/ccache/srfi/srfi-98.go +0 -0
- data/lib/guile/2.2/ccache/statprof.go +0 -0
- data/lib/guile/2.2/ccache/sxml/apply-templates.go +0 -0
- data/lib/guile/2.2/ccache/sxml/fold.go +0 -0
- data/lib/guile/2.2/ccache/sxml/match.go +0 -0
- data/lib/guile/2.2/ccache/sxml/simple.go +0 -0
- data/lib/guile/2.2/ccache/sxml/ssax/input-parse.go +0 -0
- data/lib/guile/2.2/ccache/sxml/ssax.go +0 -0
- data/lib/guile/2.2/ccache/sxml/transform.go +0 -0
- data/lib/guile/2.2/ccache/sxml/xpath.go +0 -0
- data/lib/guile/2.2/ccache/system/base/ck.go +0 -0
- data/lib/guile/2.2/ccache/system/base/compile.go +0 -0
- data/lib/guile/2.2/ccache/system/base/lalr.go +0 -0
- data/lib/guile/2.2/ccache/system/base/language.go +0 -0
- data/lib/guile/2.2/ccache/system/base/message.go +0 -0
- data/lib/guile/2.2/ccache/system/base/pmatch.go +0 -0
- data/lib/guile/2.2/ccache/system/base/syntax.go +0 -0
- data/lib/guile/2.2/ccache/system/base/target.go +0 -0
- data/lib/guile/2.2/ccache/system/base/types.go +0 -0
- data/lib/guile/2.2/ccache/system/foreign-object.go +0 -0
- data/lib/guile/2.2/ccache/system/foreign.go +0 -0
- data/lib/guile/2.2/ccache/system/repl/command.go +0 -0
- data/lib/guile/2.2/ccache/system/repl/common.go +0 -0
- data/lib/guile/2.2/ccache/system/repl/coop-server.go +0 -0
- data/lib/guile/2.2/ccache/system/repl/debug.go +0 -0
- data/lib/guile/2.2/ccache/system/repl/error-handling.go +0 -0
- data/lib/guile/2.2/ccache/system/repl/repl.go +0 -0
- data/lib/guile/2.2/ccache/system/repl/server.go +0 -0
- data/lib/guile/2.2/ccache/system/syntax.go +0 -0
- data/lib/guile/2.2/ccache/system/vm/assembler.go +0 -0
- data/lib/guile/2.2/ccache/system/vm/coverage.go +0 -0
- data/lib/guile/2.2/ccache/system/vm/debug.go +0 -0
- data/lib/guile/2.2/ccache/system/vm/disassembler.go +0 -0
- data/lib/guile/2.2/ccache/system/vm/dwarf.go +0 -0
- data/lib/guile/2.2/ccache/system/vm/elf.go +0 -0
- data/lib/guile/2.2/ccache/system/vm/frame.go +0 -0
- data/lib/guile/2.2/ccache/system/vm/inspect.go +0 -0
- data/lib/guile/2.2/ccache/system/vm/linker.go +0 -0
- data/lib/guile/2.2/ccache/system/vm/loader.go +0 -0
- data/lib/guile/2.2/ccache/system/vm/program.go +0 -0
- data/lib/guile/2.2/ccache/system/vm/trace.go +0 -0
- data/lib/guile/2.2/ccache/system/vm/trap-state.go +0 -0
- data/lib/guile/2.2/ccache/system/vm/traps.go +0 -0
- data/lib/guile/2.2/ccache/system/vm/vm.go +0 -0
- data/lib/guile/2.2/ccache/system/xref.go +0 -0
- data/lib/guile/2.2/ccache/texinfo/docbook.go +0 -0
- data/lib/guile/2.2/ccache/texinfo/html.go +0 -0
- data/lib/guile/2.2/ccache/texinfo/indexing.go +0 -0
- data/lib/guile/2.2/ccache/texinfo/plain-text.go +0 -0
- data/lib/guile/2.2/ccache/texinfo/reflection.go +0 -0
- data/lib/guile/2.2/ccache/texinfo/serialize.go +0 -0
- data/lib/guile/2.2/ccache/texinfo/string-utils.go +0 -0
- data/lib/guile/2.2/ccache/texinfo.go +0 -0
- data/lib/guile/2.2/ccache/web/client.go +0 -0
- data/lib/guile/2.2/ccache/web/http.go +0 -0
- data/lib/guile/2.2/ccache/web/request.go +0 -0
- data/lib/guile/2.2/ccache/web/response.go +0 -0
- data/lib/guile/2.2/ccache/web/server/http.go +0 -0
- data/lib/guile/2.2/ccache/web/server.go +0 -0
- data/lib/guile/2.2/ccache/web/uri.go +0 -0
- data/lib/guile.rb +19 -0
- data/lib/lilypond/2.24.1/ccache/lily/accreg.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/auto-beam.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/autochange.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/backend-library.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/bar-line.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/breath.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/c++.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/chord-entry.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/chord-ignatzek-names.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/chord-name.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/clip-region.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/color.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/curried-definitions.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/define-context-properties.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/define-event-classes.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/define-grob-interfaces.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/define-grob-properties.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/define-grobs.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/define-markup-commands.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/define-music-callbacks.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/define-music-display-methods.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/define-music-properties.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/define-music-types.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/define-note-names.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/define-stencil-commands.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/define-woodwind-diagrams.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/display-lily.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/display-woodwind-diagrams.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/file-cache.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/flag-styles.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/font-encodings.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/font.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/framework-cairo.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/framework-ps.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/framework-svg.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/fret-diagrams.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/graphviz.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/harp-pedals.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/layout-beam.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/layout-slur.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/lily-library.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/lily.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/ly-syntax-constructors.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/markup-macros.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/markup.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/midi.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/modal-transforms.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/music-functions.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/output-lib.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/output-ps.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/output-svg.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/page.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/paper-system.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/paper.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/parser-clef.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/parser-ly-from-scheme.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/part-combiner.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/predefined-fretboards.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/ps-to-png.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/scheme-engravers.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/scheme-performers.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/script.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/skyline.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/song-util.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/song.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/stencil.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/tablature.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/time-signature-settings.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/time-signature.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/titling.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/to-xml.go +0 -0
- data/lib/lilypond/2.24.1/ccache/lily/translation-functions.go +0 -0
- data/lib/lilypond/builder.rb +161 -0
- data/lib/lilypond-ruby.rb +18 -3
- data/share/emacs/site-lisp/lilypond-font-lock.el +208 -0
- data/share/emacs/site-lisp/lilypond-indent.el +605 -0
- data/share/emacs/site-lisp/lilypond-init.el +21 -0
- data/share/emacs/site-lisp/lilypond-mode.el +1204 -0
- data/share/emacs/site-lisp/lilypond-song.el +556 -0
- data/share/emacs/site-lisp/lilypond-what-beat.el +279 -0
- data/share/emacs/site-lisp/lilypond-words.el +1428 -0
- data/share/guile/2.2/guile-procedures.txt +8860 -0
- data/share/guile/2.2/ice-9/and-let-star.scm +73 -0
- data/share/guile/2.2/ice-9/arrays.scm +70 -0
- data/share/guile/2.2/ice-9/atomic.scm +38 -0
- data/share/guile/2.2/ice-9/binary-ports.scm +53 -0
- data/share/guile/2.2/ice-9/boot-9.scm +4131 -0
- data/share/guile/2.2/ice-9/buffered-input.scm +109 -0
- data/share/guile/2.2/ice-9/calling.scm +326 -0
- data/share/guile/2.2/ice-9/channel.scm +170 -0
- data/share/guile/2.2/ice-9/command-line.scm +477 -0
- data/share/guile/2.2/ice-9/common-list.scm +278 -0
- data/share/guile/2.2/ice-9/control.scm +110 -0
- data/share/guile/2.2/ice-9/curried-definitions.scm +57 -0
- data/share/guile/2.2/ice-9/debug.scm +25 -0
- data/share/guile/2.2/ice-9/deprecated.scm +93 -0
- data/share/guile/2.2/ice-9/documentation.scm +203 -0
- data/share/guile/2.2/ice-9/eval-string.scm +90 -0
- data/share/guile/2.2/ice-9/eval.scm +723 -0
- data/share/guile/2.2/ice-9/expect.scm +171 -0
- data/share/guile/2.2/ice-9/fdes-finalizers.scm +25 -0
- data/share/guile/2.2/ice-9/format.scm +1626 -0
- data/share/guile/2.2/ice-9/ftw.scm +564 -0
- data/share/guile/2.2/ice-9/futures.scm +308 -0
- data/share/guile/2.2/ice-9/gap-buffer.scm +283 -0
- data/share/guile/2.2/ice-9/getopt-long.scm +371 -0
- data/share/guile/2.2/ice-9/hash-table.scm +45 -0
- data/share/guile/2.2/ice-9/hcons.scm +80 -0
- data/share/guile/2.2/ice-9/history.scm +65 -0
- data/share/guile/2.2/ice-9/i18n.scm +531 -0
- data/share/guile/2.2/ice-9/iconv.scm +95 -0
- data/share/guile/2.2/ice-9/lineio.scm +115 -0
- data/share/guile/2.2/ice-9/list.scm +36 -0
- data/share/guile/2.2/ice-9/local-eval.scm +261 -0
- data/share/guile/2.2/ice-9/ls.scm +94 -0
- data/share/guile/2.2/ice-9/mapping.scm +118 -0
- data/share/guile/2.2/ice-9/match.scm +59 -0
- data/share/guile/2.2/ice-9/match.upstream.scm +917 -0
- data/share/guile/2.2/ice-9/networking.scm +94 -0
- data/share/guile/2.2/ice-9/null.scm +34 -0
- data/share/guile/2.2/ice-9/occam-channel.scm +261 -0
- data/share/guile/2.2/ice-9/optargs.scm +381 -0
- data/share/guile/2.2/ice-9/peg/cache.scm +45 -0
- data/share/guile/2.2/ice-9/peg/codegen.scm +359 -0
- data/share/guile/2.2/ice-9/peg/simplify-tree.scm +97 -0
- data/share/guile/2.2/ice-9/peg/string-peg.scm +273 -0
- data/share/guile/2.2/ice-9/peg/using-parsers.scm +116 -0
- data/share/guile/2.2/ice-9/peg.scm +42 -0
- data/share/guile/2.2/ice-9/poe.scm +116 -0
- data/share/guile/2.2/ice-9/poll.scm +172 -0
- data/share/guile/2.2/ice-9/popen.scm +178 -0
- data/share/guile/2.2/ice-9/ports.scm +566 -0
- data/share/guile/2.2/ice-9/posix.scm +75 -0
- data/share/guile/2.2/ice-9/pretty-print.scm +483 -0
- data/share/guile/2.2/ice-9/psyntax-pp.scm +3542 -0
- data/share/guile/2.2/ice-9/psyntax.scm +3326 -0
- data/share/guile/2.2/ice-9/q.scm +153 -0
- data/share/guile/2.2/ice-9/quasisyntax.scm +136 -0
- data/share/guile/2.2/ice-9/r5rs.scm +45 -0
- data/share/guile/2.2/ice-9/r6rs-libraries.scm +242 -0
- data/share/guile/2.2/ice-9/rdelim.scm +208 -0
- data/share/guile/2.2/ice-9/receive.scm +26 -0
- data/share/guile/2.2/ice-9/regex.scm +229 -0
- data/share/guile/2.2/ice-9/runq.scm +241 -0
- data/share/guile/2.2/ice-9/rw.scm +27 -0
- data/share/guile/2.2/ice-9/safe-r5rs.scm +145 -0
- data/share/guile/2.2/ice-9/safe.scm +34 -0
- data/share/guile/2.2/ice-9/sandbox.scm +1399 -0
- data/share/guile/2.2/ice-9/save-stack.scm +58 -0
- data/share/guile/2.2/ice-9/scm-style-repl.scm +279 -0
- data/share/guile/2.2/ice-9/serialize.scm +114 -0
- data/share/guile/2.2/ice-9/session.scm +530 -0
- data/share/guile/2.2/ice-9/slib.scm +33 -0
- data/share/guile/2.2/ice-9/stack-catch.scm +47 -0
- data/share/guile/2.2/ice-9/streams.scm +168 -0
- data/share/guile/2.2/ice-9/string-fun.scm +280 -0
- data/share/guile/2.2/ice-9/suspendable-ports.scm +788 -0
- data/share/guile/2.2/ice-9/syncase.scm +37 -0
- data/share/guile/2.2/ice-9/textual-ports.scm +70 -0
- data/share/guile/2.2/ice-9/threads.scm +392 -0
- data/share/guile/2.2/ice-9/time.scm +58 -0
- data/share/guile/2.2/ice-9/top-repl.scm +78 -0
- data/share/guile/2.2/ice-9/unicode.scm +26 -0
- data/share/guile/2.2/ice-9/vlist.scm +595 -0
- data/share/guile/2.2/ice-9/weak-vector.scm +31 -0
- data/share/guile/2.2/language/brainfuck/compile-scheme.scm +123 -0
- data/share/guile/2.2/language/brainfuck/compile-tree-il.scm +184 -0
- data/share/guile/2.2/language/brainfuck/parse.scm +95 -0
- data/share/guile/2.2/language/brainfuck/spec.scm +43 -0
- data/share/guile/2.2/language/bytecode/spec.scm +42 -0
- data/share/guile/2.2/language/bytecode.scm +104 -0
- data/share/guile/2.2/language/cps/closure-conversion.scm +848 -0
- data/share/guile/2.2/language/cps/compile-bytecode.scm +610 -0
- data/share/guile/2.2/language/cps/constructors.scm +106 -0
- data/share/guile/2.2/language/cps/contification.scm +448 -0
- data/share/guile/2.2/language/cps/cse.scm +414 -0
- data/share/guile/2.2/language/cps/dce.scm +363 -0
- data/share/guile/2.2/language/cps/effects-analysis.scm +597 -0
- data/share/guile/2.2/language/cps/elide-values.scm +88 -0
- data/share/guile/2.2/language/cps/handle-interrupts.scm +69 -0
- data/share/guile/2.2/language/cps/intmap.scm +765 -0
- data/share/guile/2.2/language/cps/intset.scm +830 -0
- data/share/guile/2.2/language/cps/licm.scm +308 -0
- data/share/guile/2.2/language/cps/optimize.scm +135 -0
- data/share/guile/2.2/language/cps/peel-loops.scm +287 -0
- data/share/guile/2.2/language/cps/primitives.scm +141 -0
- data/share/guile/2.2/language/cps/prune-bailouts.scm +86 -0
- data/share/guile/2.2/language/cps/prune-top-level-scopes.scm +63 -0
- data/share/guile/2.2/language/cps/reify-primitives.scm +179 -0
- data/share/guile/2.2/language/cps/renumber.scm +217 -0
- data/share/guile/2.2/language/cps/rotate-loops.scm +239 -0
- data/share/guile/2.2/language/cps/self-references.scm +79 -0
- data/share/guile/2.2/language/cps/simplify.scm +274 -0
- data/share/guile/2.2/language/cps/slot-allocation.scm +1058 -0
- data/share/guile/2.2/language/cps/spec.scm +51 -0
- data/share/guile/2.2/language/cps/specialize-numbers.scm +724 -0
- data/share/guile/2.2/language/cps/specialize-primcalls.scm +87 -0
- data/share/guile/2.2/language/cps/split-rec.scm +174 -0
- data/share/guile/2.2/language/cps/type-checks.scm +72 -0
- data/share/guile/2.2/language/cps/type-fold.scm +455 -0
- data/share/guile/2.2/language/cps/types.scm +1826 -0
- data/share/guile/2.2/language/cps/utils.scm +550 -0
- data/share/guile/2.2/language/cps/verify.scm +304 -0
- data/share/guile/2.2/language/cps/with-cps.scm +145 -0
- data/share/guile/2.2/language/cps.scm +358 -0
- data/share/guile/2.2/language/ecmascript/array.scm +121 -0
- data/share/guile/2.2/language/ecmascript/base.scm +251 -0
- data/share/guile/2.2/language/ecmascript/compile-tree-il.scm +576 -0
- data/share/guile/2.2/language/ecmascript/function.scm +78 -0
- data/share/guile/2.2/language/ecmascript/impl.scm +169 -0
- data/share/guile/2.2/language/ecmascript/parse.scm +352 -0
- data/share/guile/2.2/language/ecmascript/spec.scm +37 -0
- data/share/guile/2.2/language/ecmascript/tokenize.scm +513 -0
- data/share/guile/2.2/language/elisp/bindings.scm +107 -0
- data/share/guile/2.2/language/elisp/boot.el +617 -0
- data/share/guile/2.2/language/elisp/compile-tree-il.scm +812 -0
- data/share/guile/2.2/language/elisp/falias.scm +47 -0
- data/share/guile/2.2/language/elisp/lexer.scm +430 -0
- data/share/guile/2.2/language/elisp/parser.scm +222 -0
- data/share/guile/2.2/language/elisp/runtime/function-slot.scm +63 -0
- data/share/guile/2.2/language/elisp/runtime/value-slot.scm +24 -0
- data/share/guile/2.2/language/elisp/runtime.scm +153 -0
- data/share/guile/2.2/language/elisp/spec.scm +43 -0
- data/share/guile/2.2/language/scheme/compile-tree-il.scm +33 -0
- data/share/guile/2.2/language/scheme/decompile-tree-il.scm +796 -0
- data/share/guile/2.2/language/scheme/spec.scm +63 -0
- data/share/guile/2.2/language/tree-il/analyze.scm +1568 -0
- data/share/guile/2.2/language/tree-il/canonicalize.scm +82 -0
- data/share/guile/2.2/language/tree-il/compile-cps.scm +1149 -0
- data/share/guile/2.2/language/tree-il/debug.scm +246 -0
- data/share/guile/2.2/language/tree-il/effects.scm +591 -0
- data/share/guile/2.2/language/tree-il/fix-letrec.scm +314 -0
- data/share/guile/2.2/language/tree-il/optimize.scm +43 -0
- data/share/guile/2.2/language/tree-il/peval.scm +1669 -0
- data/share/guile/2.2/language/tree-il/primitives.scm +630 -0
- data/share/guile/2.2/language/tree-il/spec.scm +46 -0
- data/share/guile/2.2/language/tree-il.scm +630 -0
- data/share/guile/2.2/language/value/spec.scm +30 -0
- data/share/guile/2.2/oop/goops/accessors.scm +72 -0
- data/share/guile/2.2/oop/goops/active-slot.scm +63 -0
- data/share/guile/2.2/oop/goops/composite-slot.scm +83 -0
- data/share/guile/2.2/oop/goops/describe.scm +189 -0
- data/share/guile/2.2/oop/goops/internal.scm +30 -0
- data/share/guile/2.2/oop/goops/save.scm +874 -0
- data/share/guile/2.2/oop/goops/simple.scm +30 -0
- data/share/guile/2.2/oop/goops/stklos.scm +74 -0
- data/share/guile/2.2/oop/goops.scm +3176 -0
- data/share/guile/2.2/rnrs/arithmetic/bitwise.scm +92 -0
- data/share/guile/2.2/rnrs/arithmetic/fixnums.scm +291 -0
- data/share/guile/2.2/rnrs/arithmetic/flonums.scm +203 -0
- data/share/guile/2.2/rnrs/base.scm +291 -0
- data/share/guile/2.2/rnrs/bytevectors.scm +83 -0
- data/share/guile/2.2/rnrs/conditions.scm +225 -0
- data/share/guile/2.2/rnrs/control.scm +22 -0
- data/share/guile/2.2/rnrs/enums.scm +152 -0
- data/share/guile/2.2/rnrs/eval.scm +39 -0
- data/share/guile/2.2/rnrs/exceptions.scm +276 -0
- data/share/guile/2.2/rnrs/files.scm +96 -0
- data/share/guile/2.2/rnrs/hashtables.scm +190 -0
- data/share/guile/2.2/rnrs/io/ports.scm +554 -0
- data/share/guile/2.2/rnrs/io/simple.scm +167 -0
- data/share/guile/2.2/rnrs/lists.scm +55 -0
- data/share/guile/2.2/rnrs/mutable-pairs.scm +23 -0
- data/share/guile/2.2/rnrs/mutable-strings.scm +23 -0
- data/share/guile/2.2/rnrs/programs.scm +22 -0
- data/share/guile/2.2/rnrs/r5rs.scm +34 -0
- data/share/guile/2.2/rnrs/records/inspection.scm +81 -0
- data/share/guile/2.2/rnrs/records/procedural.scm +289 -0
- data/share/guile/2.2/rnrs/records/syntactic.scm +248 -0
- data/share/guile/2.2/rnrs/sorting.scm +27 -0
- data/share/guile/2.2/rnrs/syntax-case.scm +68 -0
- data/share/guile/2.2/rnrs/unicode.scm +104 -0
- data/share/guile/2.2/rnrs.scm +289 -0
- data/share/guile/2.2/scripts/api-diff.scm +179 -0
- data/share/guile/2.2/scripts/autofrisk.scm +218 -0
- data/share/guile/2.2/scripts/compile.scm +273 -0
- data/share/guile/2.2/scripts/disassemble.scm +38 -0
- data/share/guile/2.2/scripts/display-commentary.scm +67 -0
- data/share/guile/2.2/scripts/doc-snarf.scm +439 -0
- data/share/guile/2.2/scripts/frisk.scm +290 -0
- data/share/guile/2.2/scripts/generate-autoload.scm +144 -0
- data/share/guile/2.2/scripts/help.scm +188 -0
- data/share/guile/2.2/scripts/lint.scm +318 -0
- data/share/guile/2.2/scripts/list.scm +91 -0
- data/share/guile/2.2/scripts/punify.scm +87 -0
- data/share/guile/2.2/scripts/read-rfc822.scm +131 -0
- data/share/guile/2.2/scripts/read-scheme-source.scm +282 -0
- data/share/guile/2.2/scripts/read-text-outline.scm +253 -0
- data/share/guile/2.2/scripts/scan-api.scm +223 -0
- data/share/guile/2.2/scripts/snarf-check-and-output-texi.scm +303 -0
- data/share/guile/2.2/scripts/snarf-guile-m4-docs.scm +86 -0
- data/share/guile/2.2/scripts/summarize-guile-TODO.scm +213 -0
- data/share/guile/2.2/scripts/use2dot.scm +110 -0
- data/share/guile/2.2/srfi/srfi-1.scm +1061 -0
- data/share/guile/2.2/srfi/srfi-10.scm +89 -0
- data/share/guile/2.2/srfi/srfi-11.scm +146 -0
- data/share/guile/2.2/srfi/srfi-111.scm +37 -0
- data/share/guile/2.2/srfi/srfi-13.scm +132 -0
- data/share/guile/2.2/srfi/srfi-14.scm +99 -0
- data/share/guile/2.2/srfi/srfi-16.scm +51 -0
- data/share/guile/2.2/srfi/srfi-17.scm +174 -0
- data/share/guile/2.2/srfi/srfi-18.scm +382 -0
- data/share/guile/2.2/srfi/srfi-19.scm +1470 -0
- data/share/guile/2.2/srfi/srfi-2.scm +31 -0
- data/share/guile/2.2/srfi/srfi-26.scm +66 -0
- data/share/guile/2.2/srfi/srfi-27.scm +96 -0
- data/share/guile/2.2/srfi/srfi-28.scm +34 -0
- data/share/guile/2.2/srfi/srfi-31.scm +35 -0
- data/share/guile/2.2/srfi/srfi-34.scm +84 -0
- data/share/guile/2.2/srfi/srfi-35.scm +351 -0
- data/share/guile/2.2/srfi/srfi-37.scm +234 -0
- data/share/guile/2.2/srfi/srfi-38.scm +207 -0
- data/share/guile/2.2/srfi/srfi-39.scm +55 -0
- data/share/guile/2.2/srfi/srfi-4/gnu.scm +80 -0
- data/share/guile/2.2/srfi/srfi-4.scm +118 -0
- data/share/guile/2.2/srfi/srfi-41.scm +505 -0
- data/share/guile/2.2/srfi/srfi-42/ec.scm +1053 -0
- data/share/guile/2.2/srfi/srfi-42.scm +66 -0
- data/share/guile/2.2/srfi/srfi-43.scm +1077 -0
- data/share/guile/2.2/srfi/srfi-45.scm +93 -0
- data/share/guile/2.2/srfi/srfi-6.scm +29 -0
- data/share/guile/2.2/srfi/srfi-60.scm +73 -0
- data/share/guile/2.2/srfi/srfi-64/testing.scm +1040 -0
- data/share/guile/2.2/srfi/srfi-64.scm +55 -0
- data/share/guile/2.2/srfi/srfi-67/compare.scm +686 -0
- data/share/guile/2.2/srfi/srfi-67.scm +88 -0
- data/share/guile/2.2/srfi/srfi-69.scm +336 -0
- data/share/guile/2.2/srfi/srfi-71.scm +267 -0
- data/share/guile/2.2/srfi/srfi-8.scm +31 -0
- data/share/guile/2.2/srfi/srfi-88.scm +53 -0
- data/share/guile/2.2/srfi/srfi-9/gnu.scm +168 -0
- data/share/guile/2.2/srfi/srfi-9.scm +351 -0
- data/share/guile/2.2/srfi/srfi-98.scm +44 -0
- data/share/guile/2.2/statprof.scm +988 -0
- data/share/guile/2.2/sxml/apply-templates.scm +102 -0
- data/share/guile/2.2/sxml/fold.scm +250 -0
- data/share/guile/2.2/sxml/match.scm +75 -0
- data/share/guile/2.2/sxml/simple.scm +408 -0
- data/share/guile/2.2/sxml/ssax/input-parse.scm +180 -0
- data/share/guile/2.2/sxml/ssax.scm +265 -0
- data/share/guile/2.2/sxml/sxml-match.ss +1181 -0
- data/share/guile/2.2/sxml/transform.scm +298 -0
- data/share/guile/2.2/sxml/upstream/SSAX.scm +3235 -0
- data/share/guile/2.2/sxml/upstream/SXML-tree-trans.scm +249 -0
- data/share/guile/2.2/sxml/upstream/SXPath-old.scm +1216 -0
- data/share/guile/2.2/sxml/upstream/assert.scm +35 -0
- data/share/guile/2.2/sxml/upstream/input-parse.scm +326 -0
- data/share/guile/2.2/sxml/xpath.scm +493 -0
- data/share/guile/2.2/system/base/ck.scm +55 -0
- data/share/guile/2.2/system/base/compile.scm +282 -0
- data/share/guile/2.2/system/base/lalr.scm +51 -0
- data/share/guile/2.2/system/base/lalr.upstream.scm +2096 -0
- data/share/guile/2.2/system/base/language.scm +119 -0
- data/share/guile/2.2/system/base/message.scm +238 -0
- data/share/guile/2.2/system/base/pmatch.scm +68 -0
- data/share/guile/2.2/system/base/syntax.scm +299 -0
- data/share/guile/2.2/system/base/target.scm +152 -0
- data/share/guile/2.2/system/base/types.scm +561 -0
- data/share/guile/2.2/system/foreign-object.scm +91 -0
- data/share/guile/2.2/system/foreign.scm +200 -0
- data/share/guile/2.2/system/repl/command.scm +946 -0
- data/share/guile/2.2/system/repl/common.scm +263 -0
- data/share/guile/2.2/system/repl/coop-server.scm +200 -0
- data/share/guile/2.2/system/repl/debug.scm +210 -0
- data/share/guile/2.2/system/repl/describe.scm +347 -0
- data/share/guile/2.2/system/repl/error-handling.scm +183 -0
- data/share/guile/2.2/system/repl/repl.scm +233 -0
- data/share/guile/2.2/system/repl/server.scm +332 -0
- data/share/guile/2.2/system/syntax.scm +33 -0
- data/share/guile/2.2/system/vm/assembler.scm +2614 -0
- data/share/guile/2.2/system/vm/coverage.scm +351 -0
- data/share/guile/2.2/system/vm/debug.scm +766 -0
- data/share/guile/2.2/system/vm/disassembler.scm +658 -0
- data/share/guile/2.2/system/vm/dwarf.scm +1852 -0
- data/share/guile/2.2/system/vm/elf.scm +1042 -0
- data/share/guile/2.2/system/vm/frame.scm +485 -0
- data/share/guile/2.2/system/vm/inspect.scm +188 -0
- data/share/guile/2.2/system/vm/linker.scm +732 -0
- data/share/guile/2.2/system/vm/loader.scm +27 -0
- data/share/guile/2.2/system/vm/program.scm +312 -0
- data/share/guile/2.2/system/vm/trace.scm +121 -0
- data/share/guile/2.2/system/vm/trap-state.scm +302 -0
- data/share/guile/2.2/system/vm/traps.scm +608 -0
- data/share/guile/2.2/system/vm/vm.scm +32 -0
- data/share/guile/2.2/system/xref.scm +369 -0
- data/share/guile/2.2/texinfo/docbook.scm +240 -0
- data/share/guile/2.2/texinfo/html.scm +279 -0
- data/share/guile/2.2/texinfo/indexing.scm +75 -0
- data/share/guile/2.2/texinfo/plain-text.scm +322 -0
- data/share/guile/2.2/texinfo/reflection.scm +585 -0
- data/share/guile/2.2/texinfo/serialize.scm +300 -0
- data/share/guile/2.2/texinfo/string-utils.scm +410 -0
- data/share/guile/2.2/texinfo.scm +1263 -0
- data/share/guile/2.2/web/client.scm +513 -0
- data/share/guile/2.2/web/http.scm +2043 -0
- data/share/guile/2.2/web/request.scm +326 -0
- data/share/guile/2.2/web/response.scm +379 -0
- data/share/guile/2.2/web/server/http.scm +183 -0
- data/share/guile/2.2/web/server.scm +397 -0
- data/share/guile/2.2/web/uri.scm +552 -0
- data/share/lilypond/2.24.1/fontconfig/0bd3dc0958fa2205aaaa8ebb13e2872b-le64.cache-8 +0 -0
- data/share/lilypond/2.24.1/fontconfig/188ac73a183f12857f63bb60a4a6d603-le64.cache-8 +0 -0
- data/share/lilypond/2.24.1/fontconfig/32b6488e5b8292a2e95c79d947e009e8-le64.cache-8 +0 -0
- data/share/lilypond/2.24.1/fontconfig/3830d5c3ddfd5cd38a049b759396e72e-le64.cache-8 +0 -0
- data/share/lilypond/2.24.1/fontconfig/3f7329c5293ffd510edef78f73874cfd-le64.cache-8 +0 -0
- data/share/lilypond/2.24.1/fontconfig/4c599c202bc5c08e2d34565a40eac3b2-le64.cache-8 +0 -0
- data/share/lilypond/2.24.1/fontconfig/57e423e26b20ab21d0f2f29c145174c3-le64.cache-8 +0 -0
- data/share/lilypond/2.24.1/fontconfig/7ef2298fde41cc6eeb7af42e48b7d293-le64.cache-8 +0 -0
- data/share/lilypond/2.24.1/fontconfig/826f6b6ef79022e2eac8af26bf4b62f2-le64.cache-8 +0 -0
- data/share/lilypond/2.24.1/fontconfig/945677eb7aeaf62f1d50efc3fb3ec7d8-le64.cache-8 +0 -0
- data/share/lilypond/2.24.1/fontconfig/95530828ff6c81d309f8258d8d02a23e-le64.cache-8 +0 -0
- data/share/lilypond/2.24.1/fontconfig/CACHEDIR.TAG +4 -0
- data/share/lilypond/2.24.1/fontconfig/bf3b770c553c462765856025a94f1ce6-le64.cache-8 +0 -0
- data/share/lilypond/2.24.1/fontconfig/c855463f699352c367813e37f3f70ea7-le64.cache-8 +0 -0
- data/share/lilypond/2.24.1/fontconfig/d3e5c4ee2ceb1fc347f91d4cefc53bc0-le64.cache-8 +0 -0
- data/share/lilypond/2.24.1/fontconfig/d589a48862398ed80a3d6066f4f56f4c-le64.cache-8 +0 -0
- data/share/lilypond/2.24.1/fontconfig/d82eb4fd963d448e2fcb7d7b793b5df3-le64.cache-8 +0 -0
- data/share/lilypond/2.24.1/fontconfig/e13b20fdb08344e0e664864cc2ede53d-le64.cache-8 +0 -0
- data/share/lilypond/2.24.1/fontconfig/e52a45a1c8c8fe895fc0fc8c4e6999b8-le64.cache-8 +0 -0
- data/share/lilypond/2.24.1/fontconfig/f1f2465696798768e9653f19e17ccdc8-le64.cache-8 +0 -0
- data/share/lilypond/2.24.1/fonts/00-lilypond-fonts.conf +99 -0
- data/share/lilypond/2.24.1/fonts/99-lilypond-fonts.conf +28 -0
- data/share/lilypond/2.24.1/fonts/otf/C059-BdIta.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/C059-Bold.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/C059-Italic.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/C059-Roman.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/NimbusMonoPS-Bold.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/NimbusMonoPS-BoldItalic.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/NimbusMonoPS-Italic.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/NimbusMonoPS-Regular.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/NimbusSans-Bold.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/NimbusSans-BoldItalic.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/NimbusSans-Italic.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/NimbusSans-Regular.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/emmentaler-11.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/emmentaler-13.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/emmentaler-14.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/emmentaler-16.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/emmentaler-18.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/emmentaler-20.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/emmentaler-23.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/emmentaler-26.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/emmentaler-brace.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/texgyrecursor-bold.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/texgyrecursor-bolditalic.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/texgyrecursor-italic.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/texgyrecursor-regular.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/texgyreheros-bold.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/texgyreheros-bolditalic.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/texgyreheros-italic.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/texgyreheros-regular.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/texgyreschola-bold.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/texgyreschola-bolditalic.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/texgyreschola-italic.otf +0 -0
- data/share/lilypond/2.24.1/fonts/otf/texgyreschola-regular.otf +0 -0
- data/share/lilypond/2.24.1/fonts/source/common-modules-and-initialization.mf +26 -0
- data/share/lilypond/2.24.1/fonts/source/debugging-settings.mf +14 -0
- data/share/lilypond/2.24.1/fonts/source/declare-autometric-parameters.mf +9 -0
- data/share/lilypond/2.24.1/fonts/source/feta-accidentals.mf +58 -0
- data/share/lilypond/2.24.1/fonts/source/feta-accordion.mf +575 -0
- data/share/lilypond/2.24.1/fonts/source/feta-alphabet-generic.mf +16 -0
- data/share/lilypond/2.24.1/fonts/source/feta-alphabet11.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-alphabet13.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-alphabet14.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-alphabet16.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-alphabet18.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-alphabet20.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-alphabet23.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-alphabet26.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-arrow.mf +114 -0
- data/share/lilypond/2.24.1/fonts/source/feta-arrowheads.mf +171 -0
- data/share/lilypond/2.24.1/fonts/source/feta-autometric.mf +303 -0
- data/share/lilypond/2.24.1/fonts/source/feta-braces-a.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-braces-b.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-braces-c.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-braces-d.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-braces-e.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-braces-f.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-braces-g.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-braces-generic.mf +47 -0
- data/share/lilypond/2.24.1/fonts/source/feta-braces-h.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-braces-i.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-braces.mf +125 -0
- data/share/lilypond/2.24.1/fonts/source/feta-brackettips.mf +100 -0
- data/share/lilypond/2.24.1/fonts/source/feta-clefs.mf +963 -0
- data/share/lilypond/2.24.1/fonts/source/feta-dots.mf +37 -0
- data/share/lilypond/2.24.1/fonts/source/feta-dynamics.mf +891 -0
- data/share/lilypond/2.24.1/fonts/source/feta-flags-generic.mf +17 -0
- data/share/lilypond/2.24.1/fonts/source/feta-flags.mf +926 -0
- data/share/lilypond/2.24.1/fonts/source/feta-flags11.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-flags13.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-flags14.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-flags16.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-flags18.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-flags20.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-flags23.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-flags26.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-flats.mf +668 -0
- data/share/lilypond/2.24.1/fonts/source/feta-macros.mf +506 -0
- data/share/lilypond/2.24.1/fonts/source/feta-naturals.mf +223 -0
- data/share/lilypond/2.24.1/fonts/source/feta-noteheads-generic.mf +17 -0
- data/share/lilypond/2.24.1/fonts/source/feta-noteheads.mf +2642 -0
- data/share/lilypond/2.24.1/fonts/source/feta-noteheads11.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-noteheads13.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-noteheads14.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-noteheads16.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-noteheads18.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-noteheads20.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-noteheads23.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-noteheads26.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta-numbers.mf +1677 -0
- data/share/lilypond/2.24.1/fonts/source/feta-other-generic.mf +27 -0
- data/share/lilypond/2.24.1/fonts/source/feta-params.mf +323 -0
- data/share/lilypond/2.24.1/fonts/source/feta-parenthesis.mf +63 -0
- data/share/lilypond/2.24.1/fonts/source/feta-pedals.mf +355 -0
- data/share/lilypond/2.24.1/fonts/source/feta-rests.mf +890 -0
- data/share/lilypond/2.24.1/fonts/source/feta-scripts.mf +2206 -0
- data/share/lilypond/2.24.1/fonts/source/feta-sharps.mf +524 -0
- data/share/lilypond/2.24.1/fonts/source/feta-sori-koron.mf +325 -0
- data/share/lilypond/2.24.1/fonts/source/feta-ties.mf +72 -0
- data/share/lilypond/2.24.1/fonts/source/feta-timesignatures.mf +119 -0
- data/share/lilypond/2.24.1/fonts/source/feta-trills.mf +321 -0
- data/share/lilypond/2.24.1/fonts/source/feta11.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta13.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta14.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta16.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta18.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta20.mf +7 -0
- data/share/lilypond/2.24.1/fonts/source/feta23.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/feta26.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan-accidentals.mf +483 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan-clefs.mf +1636 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan-custodes.mf +503 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan-dots.mf +62 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan-flags.mf +319 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan-macros.mf +225 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan-noteheads-generic.mf +16 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan-noteheads.mf +2191 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan-noteheads11.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan-noteheads13.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan-noteheads14.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan-noteheads16.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan-noteheads18.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan-noteheads20.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan-noteheads23.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan-noteheads26.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan-other-generic.mf +24 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan-rests.mf +428 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan-scripts.mf +284 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan-timesignatures.mf +402 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan11.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan13.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan14.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan16.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan18.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan20.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan23.mf +6 -0
- data/share/lilypond/2.24.1/fonts/source/parmesan26.mf +6 -0
- data/share/lilypond/2.24.1/fonts/svg/emmentaler-11.svg +2525 -0
- data/share/lilypond/2.24.1/fonts/svg/emmentaler-11.woff +0 -0
- data/share/lilypond/2.24.1/fonts/svg/emmentaler-13.svg +2530 -0
- data/share/lilypond/2.24.1/fonts/svg/emmentaler-13.woff +0 -0
- data/share/lilypond/2.24.1/fonts/svg/emmentaler-14.svg +2526 -0
- data/share/lilypond/2.24.1/fonts/svg/emmentaler-14.woff +0 -0
- data/share/lilypond/2.24.1/fonts/svg/emmentaler-16.svg +2523 -0
- data/share/lilypond/2.24.1/fonts/svg/emmentaler-16.woff +0 -0
- data/share/lilypond/2.24.1/fonts/svg/emmentaler-18.svg +2519 -0
- data/share/lilypond/2.24.1/fonts/svg/emmentaler-18.woff +0 -0
- data/share/lilypond/2.24.1/fonts/svg/emmentaler-20.svg +2512 -0
- data/share/lilypond/2.24.1/fonts/svg/emmentaler-20.woff +0 -0
- data/share/lilypond/2.24.1/fonts/svg/emmentaler-23.svg +2506 -0
- data/share/lilypond/2.24.1/fonts/svg/emmentaler-23.woff +0 -0
- data/share/lilypond/2.24.1/fonts/svg/emmentaler-26.svg +2510 -0
- data/share/lilypond/2.24.1/fonts/svg/emmentaler-26.woff +0 -0
- data/share/lilypond/2.24.1/fonts/svg/emmentaler-brace.svg +1757 -0
- data/share/lilypond/2.24.1/fonts/svg/emmentaler-brace.woff +0 -0
- data/share/lilypond/2.24.1/ly/Welcome_to_LilyPond.ly +45 -0
- data/share/lilypond/2.24.1/ly/arabic.ly +185 -0
- data/share/lilypond/2.24.1/ly/articulate.ly +1013 -0
- data/share/lilypond/2.24.1/ly/bagpipe.ly +368 -0
- data/share/lilypond/2.24.1/ly/base-tkit.ly +135 -0
- data/share/lilypond/2.24.1/ly/catalan.ly +23 -0
- data/share/lilypond/2.24.1/ly/chord-modifiers-init.ly +63 -0
- data/share/lilypond/2.24.1/ly/chord-repetition-init.ly +60 -0
- data/share/lilypond/2.24.1/ly/context-mods-init.ly +119 -0
- data/share/lilypond/2.24.1/ly/declarations-init.ly +167 -0
- data/share/lilypond/2.24.1/ly/deutsch.ly +23 -0
- data/share/lilypond/2.24.1/ly/drumpitch-init.ly +366 -0
- data/share/lilypond/2.24.1/ly/dynamic-scripts-init.ly +54 -0
- data/share/lilypond/2.24.1/ly/english.ly +23 -0
- data/share/lilypond/2.24.1/ly/engraver-init.ly +1619 -0
- data/share/lilypond/2.24.1/ly/espanol.ly +23 -0
- data/share/lilypond/2.24.1/ly/event-listener.ly +241 -0
- data/share/lilypond/2.24.1/ly/festival.ly +38 -0
- data/share/lilypond/2.24.1/ly/generate-documentation.ly +7 -0
- data/share/lilypond/2.24.1/ly/grace-init.ly +56 -0
- data/share/lilypond/2.24.1/ly/graphviz-init.ly +174 -0
- data/share/lilypond/2.24.1/ly/gregorian.ly +268 -0
- data/share/lilypond/2.24.1/ly/guile-debugger.ly +55 -0
- data/share/lilypond/2.24.1/ly/hel-arabic.ly +307 -0
- data/share/lilypond/2.24.1/ly/init.ly +96 -0
- data/share/lilypond/2.24.1/ly/italiano.ly +23 -0
- data/share/lilypond/2.24.1/ly/lilypond-book-preamble.ly +47 -0
- data/share/lilypond/2.24.1/ly/lyrics-tkit.ly +68 -0
- data/share/lilypond/2.24.1/ly/makam.ly +166 -0
- data/share/lilypond/2.24.1/ly/midi-init.ly +59 -0
- data/share/lilypond/2.24.1/ly/music-functions-init.ly +2254 -0
- data/share/lilypond/2.24.1/ly/nederlands.ly +23 -0
- data/share/lilypond/2.24.1/ly/norsk.ly +23 -0
- data/share/lilypond/2.24.1/ly/paper-defaults-init.ly +188 -0
- data/share/lilypond/2.24.1/ly/performer-init.ly +398 -0
- data/share/lilypond/2.24.1/ly/persian.ly +335 -0
- data/share/lilypond/2.24.1/ly/piano-tkit.ly +61 -0
- data/share/lilypond/2.24.1/ly/portugues.ly +23 -0
- data/share/lilypond/2.24.1/ly/predefined-fretboards-init.ly +78 -0
- data/share/lilypond/2.24.1/ly/predefined-guitar-fretboards.ly +506 -0
- data/share/lilypond/2.24.1/ly/predefined-guitar-ninth-fretboards.ly +75 -0
- data/share/lilypond/2.24.1/ly/predefined-mandolin-fretboards.ly +876 -0
- data/share/lilypond/2.24.1/ly/predefined-ukulele-fretboards.ly +1285 -0
- data/share/lilypond/2.24.1/ly/property-init.ly +858 -0
- data/share/lilypond/2.24.1/ly/satb.ly +214 -0
- data/share/lilypond/2.24.1/ly/scale-definitions-init.ly +117 -0
- data/share/lilypond/2.24.1/ly/scheme-sandbox.ly +39 -0
- data/share/lilypond/2.24.1/ly/script-init.ly +94 -0
- data/share/lilypond/2.24.1/ly/spanners-init.ly +146 -0
- data/share/lilypond/2.24.1/ly/ssaattbb.ly +335 -0
- data/share/lilypond/2.24.1/ly/staff-tkit.ly +182 -0
- data/share/lilypond/2.24.1/ly/string-tunings-init.ly +94 -0
- data/share/lilypond/2.24.1/ly/suomi.ly +23 -0
- data/share/lilypond/2.24.1/ly/svenska.ly +23 -0
- data/share/lilypond/2.24.1/ly/swing.ly +362 -0
- data/share/lilypond/2.24.1/ly/text-replacements.ly +150 -0
- data/share/lilypond/2.24.1/ly/titling-init.ly +150 -0
- data/share/lilypond/2.24.1/ly/toc-init.ly +182 -0
- data/share/lilypond/2.24.1/ly/turkish-makam.ly +609 -0
- data/share/lilypond/2.24.1/ly/vlaams.ly +23 -0
- data/share/lilypond/2.24.1/ly/vocal-tkit.ly +103 -0
- data/share/lilypond/2.24.1/ly/voice-tkit.ly +34 -0
- data/share/lilypond/2.24.1/ps/encodingdefs.ps +2611 -0
- data/share/lilypond/2.24.1/ps/lilyponddefs.ps +49 -0
- data/share/lilypond/2.24.1/ps/music-drawing-routines.ps +329 -0
- data/share/lilypond/2.24.1/python/__pycache__/book_base.cpython-310.pyc +0 -0
- data/share/lilypond/2.24.1/python/__pycache__/book_docbook.cpython-310.pyc +0 -0
- data/share/lilypond/2.24.1/python/__pycache__/book_html.cpython-310.pyc +0 -0
- data/share/lilypond/2.24.1/python/__pycache__/book_latex.cpython-310.pyc +0 -0
- data/share/lilypond/2.24.1/python/__pycache__/book_snippets.cpython-310.pyc +0 -0
- data/share/lilypond/2.24.1/python/__pycache__/book_texinfo.cpython-310.pyc +0 -0
- data/share/lilypond/2.24.1/python/__pycache__/convertrules.cpython-310.pyc +0 -0
- data/share/lilypond/2.24.1/python/__pycache__/langdefs.cpython-310.pyc +0 -0
- data/share/lilypond/2.24.1/python/__pycache__/lilylib.cpython-310.pyc +0 -0
- data/share/lilypond/2.24.1/python/__pycache__/midi.cpython-310.pyc +0 -0
- data/share/lilypond/2.24.1/python/__pycache__/musicexp.cpython-310.pyc +0 -0
- data/share/lilypond/2.24.1/python/__pycache__/musicxml.cpython-310.pyc +0 -0
- data/share/lilypond/2.24.1/python/__pycache__/musicxml2ly_conversion.cpython-310.pyc +0 -0
- data/share/lilypond/2.24.1/python/__pycache__/utilities.cpython-310.pyc +0 -0
- data/share/lilypond/2.24.1/python/book_base.py +331 -0
- data/share/lilypond/2.24.1/python/book_docbook.py +154 -0
- data/share/lilypond/2.24.1/python/book_html.py +178 -0
- data/share/lilypond/2.24.1/python/book_latex.py +373 -0
- data/share/lilypond/2.24.1/python/book_snippets.py +1052 -0
- data/share/lilypond/2.24.1/python/book_texinfo.py +437 -0
- data/share/lilypond/2.24.1/python/convertrules.py +4764 -0
- data/share/lilypond/2.24.1/python/langdefs.py +131 -0
- data/share/lilypond/2.24.1/python/lilylib.py +141 -0
- data/share/lilypond/2.24.1/python/midi.py +212 -0
- data/share/lilypond/2.24.1/python/musicexp.py +2781 -0
- data/share/lilypond/2.24.1/python/musicxml.py +1905 -0
- data/share/lilypond/2.24.1/python/musicxml2ly_conversion.py +80 -0
- data/share/lilypond/2.24.1/python/utilities.py +280 -0
- data/share/lilypond/2.24.1/scm/lily/accreg.scm +579 -0
- data/share/lilypond/2.24.1/scm/lily/auto-beam.scm +163 -0
- data/share/lilypond/2.24.1/scm/lily/autochange.scm +100 -0
- data/share/lilypond/2.24.1/scm/lily/backend-library.scm +593 -0
- data/share/lilypond/2.24.1/scm/lily/bar-line.scm +1281 -0
- data/share/lilypond/2.24.1/scm/lily/breath.scm +74 -0
- data/share/lilypond/2.24.1/scm/lily/c++.scm +174 -0
- data/share/lilypond/2.24.1/scm/lily/chord-entry.scm +278 -0
- data/share/lilypond/2.24.1/scm/lily/chord-ignatzek-names.scm +304 -0
- data/share/lilypond/2.24.1/scm/lily/chord-name.scm +217 -0
- data/share/lilypond/2.24.1/scm/lily/clip-region.scm +87 -0
- data/share/lilypond/2.24.1/scm/lily/color.scm +757 -0
- data/share/lilypond/2.24.1/scm/lily/curried-definitions.scm +68 -0
- data/share/lilypond/2.24.1/scm/lily/define-context-properties.scm +939 -0
- data/share/lilypond/2.24.1/scm/lily/define-event-classes.scm +142 -0
- data/share/lilypond/2.24.1/scm/lily/define-grob-interfaces.scm +640 -0
- data/share/lilypond/2.24.1/scm/lily/define-grob-properties.scm +1647 -0
- data/share/lilypond/2.24.1/scm/lily/define-grobs.scm +4027 -0
- data/share/lilypond/2.24.1/scm/lily/define-markup-commands.scm +5737 -0
- data/share/lilypond/2.24.1/scm/lily/define-music-callbacks.scm +257 -0
- data/share/lilypond/2.24.1/scm/lily/define-music-display-methods.scm +1350 -0
- data/share/lilypond/2.24.1/scm/lily/define-music-properties.scm +242 -0
- data/share/lilypond/2.24.1/scm/lily/define-music-types.scm +983 -0
- data/share/lilypond/2.24.1/scm/lily/define-note-names.scm +1421 -0
- data/share/lilypond/2.24.1/scm/lily/define-stencil-commands.scm +71 -0
- data/share/lilypond/2.24.1/scm/lily/define-woodwind-diagrams.scm +1215 -0
- data/share/lilypond/2.24.1/scm/lily/display-lily.scm +315 -0
- data/share/lilypond/2.24.1/scm/lily/display-woodwind-diagrams.scm +1985 -0
- data/share/lilypond/2.24.1/scm/lily/document-backend.scm +307 -0
- data/share/lilypond/2.24.1/scm/lily/document-context-mods.scm +98 -0
- data/share/lilypond/2.24.1/scm/lily/document-functions.scm +169 -0
- data/share/lilypond/2.24.1/scm/lily/document-identifiers.scm +76 -0
- data/share/lilypond/2.24.1/scm/lily/document-markup.scm +158 -0
- data/share/lilypond/2.24.1/scm/lily/document-music.scm +146 -0
- data/share/lilypond/2.24.1/scm/lily/document-outside-staff-priorities.scm +40 -0
- data/share/lilypond/2.24.1/scm/lily/document-paper-sizes.scm +71 -0
- data/share/lilypond/2.24.1/scm/lily/document-translation.scm +318 -0
- data/share/lilypond/2.24.1/scm/lily/document-type-predicates.scm +85 -0
- data/share/lilypond/2.24.1/scm/lily/documentation-generate.scm +259 -0
- data/share/lilypond/2.24.1/scm/lily/documentation-lib.scm +207 -0
- data/share/lilypond/2.24.1/scm/lily/file-cache.scm +28 -0
- data/share/lilypond/2.24.1/scm/lily/flag-styles.scm +249 -0
- data/share/lilypond/2.24.1/scm/lily/font-encodings.scm +1242 -0
- data/share/lilypond/2.24.1/scm/lily/font.scm +303 -0
- data/share/lilypond/2.24.1/scm/lily/framework-cairo.scm +26 -0
- data/share/lilypond/2.24.1/scm/lily/framework-ps.scm +896 -0
- data/share/lilypond/2.24.1/scm/lily/framework-svg.scm +172 -0
- data/share/lilypond/2.24.1/scm/lily/fret-diagrams.scm +1261 -0
- data/share/lilypond/2.24.1/scm/lily/graphviz.scm +78 -0
- data/share/lilypond/2.24.1/scm/lily/guile-debugger.scm +90 -0
- data/share/lilypond/2.24.1/scm/lily/harp-pedals.scm +172 -0
- data/share/lilypond/2.24.1/scm/lily/hyphenate-internal-words.scm +51 -0
- data/share/lilypond/2.24.1/scm/lily/layout-beam.scm +73 -0
- data/share/lilypond/2.24.1/scm/lily/layout-slur.scm +45 -0
- data/share/lilypond/2.24.1/scm/lily/lily-library.scm +1446 -0
- data/share/lilypond/2.24.1/scm/lily/lily-sort.scm +116 -0
- data/share/lilypond/2.24.1/scm/lily/lily.scm +929 -0
- data/share/lilypond/2.24.1/scm/lily/ly-syntax-constructors.scm +374 -0
- data/share/lilypond/2.24.1/scm/lily/markup-macros.scm +493 -0
- data/share/lilypond/2.24.1/scm/lily/markup.scm +126 -0
- data/share/lilypond/2.24.1/scm/lily/midi.scm +258 -0
- data/share/lilypond/2.24.1/scm/lily/modal-transforms.scm +337 -0
- data/share/lilypond/2.24.1/scm/lily/music-functions.scm +2878 -0
- data/share/lilypond/2.24.1/scm/lily/output-lib.scm +3377 -0
- data/share/lilypond/2.24.1/scm/lily/output-ps.scm +335 -0
- data/share/lilypond/2.24.1/scm/lily/output-svg.scm +684 -0
- data/share/lilypond/2.24.1/scm/lily/page.scm +321 -0
- data/share/lilypond/2.24.1/scm/lily/paper-system.scm +271 -0
- data/share/lilypond/2.24.1/scm/lily/paper.scm +376 -0
- data/share/lilypond/2.24.1/scm/lily/parser-clef.scm +205 -0
- data/share/lilypond/2.24.1/scm/lily/parser-ly-from-scheme.scm +170 -0
- data/share/lilypond/2.24.1/scm/lily/part-combiner.scm +998 -0
- data/share/lilypond/2.24.1/scm/lily/predefined-fretboards.scm +54 -0
- data/share/lilypond/2.24.1/scm/lily/ps-to-png.scm +182 -0
- data/share/lilypond/2.24.1/scm/lily/scheme-engravers.scm +1813 -0
- data/share/lilypond/2.24.1/scm/lily/scheme-performers.scm +126 -0
- data/share/lilypond/2.24.1/scm/lily/script.scm +416 -0
- data/share/lilypond/2.24.1/scm/lily/skyline.scm +25 -0
- data/share/lilypond/2.24.1/scm/lily/song-util.scm +191 -0
- data/share/lilypond/2.24.1/scm/lily/song.scm +853 -0
- data/share/lilypond/2.24.1/scm/lily/stencil.scm +998 -0
- data/share/lilypond/2.24.1/scm/lily/tablature.scm +392 -0
- data/share/lilypond/2.24.1/scm/lily/time-signature-settings.scm +473 -0
- data/share/lilypond/2.24.1/scm/lily/time-signature.scm +35 -0
- data/share/lilypond/2.24.1/scm/lily/titling.scm +99 -0
- data/share/lilypond/2.24.1/scm/lily/to-xml.scm +254 -0
- data/share/lilypond/2.24.1/scm/lily/translation-functions.scm +1169 -0
- data/share/lilypond/2.24.1/vim/compiler/lilypond.vim +36 -0
- data/share/lilypond/2.24.1/vim/ftdetect/lilypond.vim +4 -0
- data/share/lilypond/2.24.1/vim/ftplugin/lilypond.vim +91 -0
- data/share/lilypond/2.24.1/vim/indent/lilypond.vim +79 -0
- data/share/lilypond/2.24.1/vim/syntax/lilypond-words +1408 -0
- data/share/lilypond/2.24.1/vim/syntax/lilypond-words.vim +3 -0
- data/share/lilypond/2.24.1/vim/syntax/lilypond.vim +104 -0
- data/share/locale/ca/LC_MESSAGES/lilypond.mo +0 -0
- data/share/locale/cs/LC_MESSAGES/lilypond.mo +0 -0
- data/share/locale/da/LC_MESSAGES/lilypond.mo +0 -0
- data/share/locale/de/LC_MESSAGES/lilypond.mo +0 -0
- data/share/locale/el/LC_MESSAGES/lilypond.mo +0 -0
- data/share/locale/eo/LC_MESSAGES/lilypond.mo +0 -0
- data/share/locale/es/LC_MESSAGES/lilypond.mo +0 -0
- data/share/locale/fi/LC_MESSAGES/lilypond.mo +0 -0
- data/share/locale/fr/LC_MESSAGES/lilypond.mo +0 -0
- data/share/locale/it/LC_MESSAGES/lilypond.mo +0 -0
- data/share/locale/ja/LC_MESSAGES/lilypond.mo +0 -0
- data/share/locale/nl/LC_MESSAGES/lilypond.mo +0 -0
- data/share/locale/ru/LC_MESSAGES/lilypond.mo +0 -0
- data/share/locale/sv/LC_MESSAGES/lilypond.mo +0 -0
- data/share/locale/tr/LC_MESSAGES/lilypond.mo +0 -0
- data/share/locale/uk/LC_MESSAGES/lilypond.mo +0 -0
- data/share/locale/vi/LC_MESSAGES/lilypond.mo +0 -0
- data/share/locale/zh_CN/LC_MESSAGES/lilypond.mo +0 -0
- data/share/locale/zh_TW/LC_MESSAGES/lilypond.mo +0 -0
- metadata +1135 -4
@@ -0,0 +1,3235 @@
|
|
1
|
+
; Functional XML parsing framework: SAX/DOM and SXML parsers
|
2
|
+
; with support for XML Namespaces and validation
|
3
|
+
;
|
4
|
+
; This is a package of low-to-high level lexing and parsing procedures
|
5
|
+
; that can be combined to yield a SAX, a DOM, a validating parsers, or
|
6
|
+
; a parser intended for a particular document type. The procedures in
|
7
|
+
; the package can be used separately to tokenize or parse various
|
8
|
+
; pieces of XML documents. The package supports XML Namespaces,
|
9
|
+
; internal and external parsed entities, user-controlled handling of
|
10
|
+
; whitespace, and validation. This module therefore is intended to be
|
11
|
+
; a framework, a set of "Lego blocks" you can use to build a parser
|
12
|
+
; following any discipline and performing validation to any degree. As
|
13
|
+
; an example of the parser construction, this file includes a
|
14
|
+
; semi-validating SXML parser.
|
15
|
+
|
16
|
+
; The present XML framework has a "sequential" feel of SAX yet a
|
17
|
+
; "functional style" of DOM. Like a SAX parser, the framework scans
|
18
|
+
; the document only once and permits incremental processing. An
|
19
|
+
; application that handles document elements in order can run as
|
20
|
+
; efficiently as possible. _Unlike_ a SAX parser, the framework does
|
21
|
+
; not require an application register stateful callbacks and surrender
|
22
|
+
; control to the parser. Rather, it is the application that can drive
|
23
|
+
; the framework -- calling its functions to get the current lexical or
|
24
|
+
; syntax element. These functions do not maintain or mutate any state
|
25
|
+
; save the input port. Therefore, the framework permits parsing of XML
|
26
|
+
; in a pure functional style, with the input port being a monad (or a
|
27
|
+
; linear, read-once parameter).
|
28
|
+
|
29
|
+
; Besides the PORT, there is another monad -- SEED. Most of the
|
30
|
+
; middle- and high-level parsers are single-threaded through the
|
31
|
+
; seed. The functions of this framework do not process or affect the
|
32
|
+
; SEED in any way: they simply pass it around as an instance of an
|
33
|
+
; opaque datatype. User functions, on the other hand, can use the
|
34
|
+
; seed to maintain user's state, to accumulate parsing results, etc. A
|
35
|
+
; user can freely mix his own functions with those of the
|
36
|
+
; framework. On the other hand, the user may wish to instantiate a
|
37
|
+
; high-level parser: ssax:make-elem-parser or ssax:make-parser. In
|
38
|
+
; the latter case, the user must provide functions of specific
|
39
|
+
; signatures, which are called at predictable moments during the
|
40
|
+
; parsing: to handle character data, element data, or processing
|
41
|
+
; instructions (PI). The functions are always given the SEED, among
|
42
|
+
; other parameters, and must return the new SEED.
|
43
|
+
|
44
|
+
; From a functional point of view, XML parsing is a combined
|
45
|
+
; pre-post-order traversal of a "tree" that is the XML document
|
46
|
+
; itself. This down-and-up traversal tells the user about an element
|
47
|
+
; when its start tag is encountered. The user is notified about the
|
48
|
+
; element once more, after all element's children have been
|
49
|
+
; handled. The process of XML parsing therefore is a fold over the
|
50
|
+
; raw XML document. Unlike a fold over trees defined in [1], the
|
51
|
+
; parser is necessarily single-threaded -- obviously as elements
|
52
|
+
; in a text XML document are laid down sequentially. The parser
|
53
|
+
; therefore is a tree fold that has been transformed to accept an
|
54
|
+
; accumulating parameter [1,2].
|
55
|
+
|
56
|
+
; Formally, the denotational semantics of the parser can be expressed
|
57
|
+
; as
|
58
|
+
; parser:: (Start-tag -> Seed -> Seed) ->
|
59
|
+
; (Start-tag -> Seed -> Seed -> Seed) ->
|
60
|
+
; (Char-Data -> Seed -> Seed) ->
|
61
|
+
; XML-text-fragment -> Seed -> Seed
|
62
|
+
; parser fdown fup fchar "<elem attrs> content </elem>" seed
|
63
|
+
; = fup "<elem attrs>" seed
|
64
|
+
; (parser fdown fup fchar "content" (fdown "<elem attrs>" seed))
|
65
|
+
;
|
66
|
+
; parser fdown fup fchar "char-data content" seed
|
67
|
+
; = parser fdown fup fchar "content" (fchar "char-data" seed)
|
68
|
+
;
|
69
|
+
; parser fdown fup fchar "elem-content content" seed
|
70
|
+
; = parser fdown fup fchar "content" (
|
71
|
+
; parser fdown fup fchar "elem-content" seed)
|
72
|
+
|
73
|
+
; Compare the last two equations with the left fold
|
74
|
+
; fold-left kons elem:list seed = fold-left kons list (kons elem seed)
|
75
|
+
|
76
|
+
; The real parser created my ssax:make-parser is slightly more complicated,
|
77
|
+
; to account for processing instructions, entity references, namespaces,
|
78
|
+
; processing of document type declaration, etc.
|
79
|
+
|
80
|
+
|
81
|
+
; The XML standard document referred to in this module is
|
82
|
+
; http://www.w3.org/TR/1998/REC-xml-19980210.html
|
83
|
+
;
|
84
|
+
; The present file also defines a procedure that parses the text of an
|
85
|
+
; XML document or of a separate element into SXML, an
|
86
|
+
; S-expression-based model of an XML Information Set. SXML is also an
|
87
|
+
; Abstract Syntax Tree of an XML document. SXML is similar
|
88
|
+
; but not identical to DOM; SXML is particularly suitable for
|
89
|
+
; Scheme-based XML/HTML authoring, SXPath queries, and tree
|
90
|
+
; transformations. See SXML.html for more details.
|
91
|
+
; SXML is a term implementation of evaluation of the XML document [3].
|
92
|
+
; The other implementation is context-passing.
|
93
|
+
|
94
|
+
; The present frameworks fully supports the XML Namespaces Recommendation:
|
95
|
+
; http://www.w3.org/TR/REC-xml-names/
|
96
|
+
; Other links:
|
97
|
+
; [1] Jeremy Gibbons, Geraint Jones, "The Under-appreciated Unfold,"
|
98
|
+
; Proc. ICFP'98, 1998, pp. 273-279.
|
99
|
+
; [2] Richard S. Bird, The promotion and accumulation strategies in
|
100
|
+
; transformational programming, ACM Trans. Progr. Lang. Systems,
|
101
|
+
; 6(4):487-504, October 1984.
|
102
|
+
; [3] Ralf Hinze, "Deriving Backtracking Monad Transformers,"
|
103
|
+
; Functional Pearl. Proc ICFP'00, pp. 186-197.
|
104
|
+
|
105
|
+
; IMPORT
|
106
|
+
; parser-error ssax:warn, see Handling of errors, below
|
107
|
+
; functions declared in files util.scm, input-parse.scm and look-for-str.scm
|
108
|
+
; char-encoding.scm for various platform-specific character-encoding functions.
|
109
|
+
; From SRFI-13: string-concatenate/shared and string-concatenate-reverse/shared
|
110
|
+
; If a particular implementation lacks SRFI-13 support, please
|
111
|
+
; include the file srfi-13-local.scm
|
112
|
+
|
113
|
+
; Handling of errors
|
114
|
+
; This package relies on a function parser-error, which must be defined
|
115
|
+
; by a user of the package. The function has the following signature:
|
116
|
+
; parser-error PORT MESSAGE SPECIALISING-MSG*
|
117
|
+
; Many procedures of this package call 'parser-error' whenever a
|
118
|
+
; parsing, well-formedness or validation error is encountered. The
|
119
|
+
; first argument is a port, which typically points to the offending
|
120
|
+
; character or its neighborhood. Most of the Scheme systems let the
|
121
|
+
; user query a PORT for the current position. The MESSAGE argument
|
122
|
+
; indicates a failed XML production or a failed XML constraint. The
|
123
|
+
; latter is referred to by its anchor name in the XML Recommendation
|
124
|
+
; or XML Namespaces Recommendation. The parsing library (e.g.,
|
125
|
+
; next-token, assert-curr-char) invoke 'parser-error' as well, in
|
126
|
+
; exactly the same way. See input-parse.scm for more details.
|
127
|
+
; See
|
128
|
+
; http://pair.com/lisovsky/download/parse-error.scm
|
129
|
+
; for an excellent example of such a redefined parser-error function.
|
130
|
+
;
|
131
|
+
; In addition, the present code invokes a function ssax:warn
|
132
|
+
; ssax:warn PORT MESSAGE SPECIALISING-MSG*
|
133
|
+
; to notify the user about warnings that are NOT errors but still
|
134
|
+
; may alert the user.
|
135
|
+
;
|
136
|
+
; Again, parser-error and ssax:warn are supposed to be defined by the
|
137
|
+
; user. However, if a run-test macro below is set to include
|
138
|
+
; self-tests, this present code does provide the definitions for these
|
139
|
+
; functions to allow tests to run.
|
140
|
+
|
141
|
+
; Misc notes
|
142
|
+
; It seems it is highly desirable to separate tests out in a dedicated
|
143
|
+
; file.
|
144
|
+
;
|
145
|
+
; Jim Bender wrote on Mon, 9 Sep 2002 20:03:42 EDT on the SSAX-SXML
|
146
|
+
; mailing list (message A fine-grained "lego")
|
147
|
+
; The task was to record precise source location information, as PLT
|
148
|
+
; does with its current XML parser. That parser records the start and
|
149
|
+
; end location (filepos, line#, column#) for pi, elements, attributes,
|
150
|
+
; chuncks of "pcdata".
|
151
|
+
; As suggested above, though, in some cases I needed to be able force
|
152
|
+
; open an interface that did not yet exist. For instance, I added an
|
153
|
+
; "end-char-data-hook", which would be called at the end of char-data
|
154
|
+
; fragment. This returns a function of type (seed -> seed) which is
|
155
|
+
; invoked on the current seed only if read-char-data has indeed reached
|
156
|
+
; the end of a block of char data (after reading a new token.
|
157
|
+
; But the deepest interface that I needed to expose was that of reading
|
158
|
+
; attributes. In the official distribution, this is not even a separate
|
159
|
+
; function. Instead, it is embedded within SSAX:read-attributes. This
|
160
|
+
; required some small re-structuring as well.
|
161
|
+
; This definitely will not be to everyone's taste (nor needed by most).
|
162
|
+
; Certainly, the existing make-parser interface addresses most custom
|
163
|
+
; needs. And likely 80-90 lines of a "link specification" to create a
|
164
|
+
; parser from many tiny little lego blocks may please only a few, while
|
165
|
+
; appalling others.
|
166
|
+
; The code is available at http://celtic.benderweb.net/ssax-lego.plt or
|
167
|
+
; http://celtic.benderweb.net/ssax-lego.tar.gz
|
168
|
+
; In the examples directory, I provide:
|
169
|
+
; - a unit version of the make-parser interface,
|
170
|
+
; - a simple SXML parser using that interface,
|
171
|
+
; - an SXML parser which directly uses the "new lego",
|
172
|
+
; - a pseudo-SXML parser, which records source location information
|
173
|
+
; - and lastly a parser which returns the structures used in PLT's xml
|
174
|
+
; collection, with source location information
|
175
|
+
|
176
|
+
; $Id: SSAX.scm,v 5.1 2004/07/07 16:02:30 sperber Exp $
|
177
|
+
;^^^^^^^^^
|
178
|
+
|
179
|
+
|
180
|
+
; See the Makefile in the ../tests directory
|
181
|
+
; (in particular, the rule vSSAX) for an example of how
|
182
|
+
; to run this code on various Scheme systems.
|
183
|
+
; See SSAX examples for many samples of using this code,
|
184
|
+
; again, on a variety of Scheme systems.
|
185
|
+
; See http://ssax.sf.net/
|
186
|
+
|
187
|
+
|
188
|
+
; The following macro runs built-in test cases -- or does not run,
|
189
|
+
; depending on which of the two cases below you commented out
|
190
|
+
; Case 1: no tests:
|
191
|
+
;(define-macro run-test (lambda body '(begin #f)))
|
192
|
+
;(define-syntax run-test (syntax-rules () ((run-test . args) (begin #f))))
|
193
|
+
|
194
|
+
; Case 2: with tests.
|
195
|
+
; The following macro could've been defined just as
|
196
|
+
; (define-macro run-test (lambda body `(begin (display "\n-->Test\n") ,@body)))
|
197
|
+
;
|
198
|
+
; Instead, it's more involved, to make up for case-insensitivity of
|
199
|
+
; symbols on some Scheme systems. In Gambit, symbols are case
|
200
|
+
; sensitive: (eq? 'A 'a) is #f and (eq? 'Aa (string->symbol "Aa")) is
|
201
|
+
; #t. On some systems, symbols are case-insensitive and just the
|
202
|
+
; opposite is true. Therefore, we introduce a notation '"ASymbol" (a
|
203
|
+
; quoted string) that stands for a case-_sensitive_ ASymbol -- on any
|
204
|
+
; R5RS Scheme system. This notation is valid only within the body of
|
205
|
+
; run-test.
|
206
|
+
; The notation is implemented by scanning the run-test's
|
207
|
+
; body and replacing every occurrence of (quote "str") with the result
|
208
|
+
; of (string->symbol "str"). We can do such a replacement at macro-expand
|
209
|
+
; time (rather than at run time).
|
210
|
+
|
211
|
+
; Here's the previous version of run-test, implemented as a low-level
|
212
|
+
; macro.
|
213
|
+
; (define-macro run-test
|
214
|
+
; (lambda body
|
215
|
+
; (define (re-write body)
|
216
|
+
; (cond
|
217
|
+
; ((vector? body)
|
218
|
+
; (list->vector (re-write (vector->list body))))
|
219
|
+
; ((not (pair? body)) body)
|
220
|
+
; ((and (eq? 'quote (car body)) (pair? (cdr body))
|
221
|
+
; (string? (cadr body)))
|
222
|
+
; (string->symbol (cadr body)))
|
223
|
+
; (else (cons (re-write (car body)) (re-write (cdr body))))))
|
224
|
+
; (cons 'begin (re-write body))))
|
225
|
+
;
|
226
|
+
; For portability, it is re-written as syntax-rules. The syntax-rules
|
227
|
+
; version is less powerful: for example, it can't handle
|
228
|
+
; (case x (('"Foo") (do-on-Foo))) whereas the low-level macro
|
229
|
+
; could correctly place a case-sensitive symbol at the right place.
|
230
|
+
; We also do not scan vectors (because we don't use them here).
|
231
|
+
; Twice-deep quasiquotes aren't handled either.
|
232
|
+
; Still, the syntax-rules version satisfies our immediate needs.
|
233
|
+
; Incidentally, I originally didn't believe that the macro below
|
234
|
+
; was at all possible.
|
235
|
+
;
|
236
|
+
; The macro is written in a continuation-passing style. A continuation
|
237
|
+
; typically has the following structure: (k-head ! . args)
|
238
|
+
; When the continuation is invoked, we expand into
|
239
|
+
; (k-head <computed-result> . arg). That is, the dedicated symbol !
|
240
|
+
; is the placeholder for the result.
|
241
|
+
;
|
242
|
+
; It seems that the most modular way to write the run-test macro would
|
243
|
+
; be the following
|
244
|
+
;
|
245
|
+
; (define-syntax run-test
|
246
|
+
; (syntax-rules ()
|
247
|
+
; ((run-test . ?body)
|
248
|
+
; (letrec-syntax
|
249
|
+
; ((scan-exp ; (scan-exp body k)
|
250
|
+
; (syntax-rules (quote quasiquote !)
|
251
|
+
; ((scan-exp (quote (hd . tl)) k)
|
252
|
+
; (scan-lit-lst (hd . tl) (do-wrap ! quasiquote k)))
|
253
|
+
; ((scan-exp (quote x) (k-head ! . args))
|
254
|
+
; (k-head
|
255
|
+
; (if (string? (quote x)) (string->symbol (quote x)) (quote x))
|
256
|
+
; . args))
|
257
|
+
; ((scan-exp (hd . tl) k)
|
258
|
+
; (scan-exp hd (do-tl ! scan-exp tl k)))
|
259
|
+
; ((scan-exp x (k-head ! . args))
|
260
|
+
; (k-head x . args))))
|
261
|
+
; (do-tl
|
262
|
+
; (syntax-rules (!)
|
263
|
+
; ((do-tl processed-hd fn () (k-head ! . args))
|
264
|
+
; (k-head (processed-hd) . args))
|
265
|
+
; ((do-tl processed-hd fn old-tl k)
|
266
|
+
; (fn old-tl (do-cons ! processed-hd k)))))
|
267
|
+
; ...
|
268
|
+
; (do-finish
|
269
|
+
; (syntax-rules ()
|
270
|
+
; ((do-finish (new-body)) new-body)
|
271
|
+
; ((do-finish new-body) (begin . new-body))))
|
272
|
+
; ...
|
273
|
+
; (scan-exp ?body (do-finish !))
|
274
|
+
; ))))
|
275
|
+
;
|
276
|
+
; Alas, that doesn't work on all systems. We hit yet another dark
|
277
|
+
; corner of the R5RS macros. The reason is that run-test is used in
|
278
|
+
; the code below to introduce definitions. For example:
|
279
|
+
; (run-test
|
280
|
+
; (define (ssax:warn port msg . other-msg)
|
281
|
+
; (apply cerr (cons* nl "Warning: " msg other-msg)))
|
282
|
+
; )
|
283
|
+
; This code expands to
|
284
|
+
; (begin
|
285
|
+
; (define (ssax:warn port msg . other-msg) ...))
|
286
|
+
; so the definition gets spliced in into the top level. Right?
|
287
|
+
; Well, On Petite Chez Scheme it is so. However, many other systems
|
288
|
+
; don't like this approach. The reason is that the invocation of
|
289
|
+
; (run-test (define (ssax:warn port msg . other-msg) ...))
|
290
|
+
; first expands into
|
291
|
+
; (letrec-syntax (...)
|
292
|
+
; (scan-exp ((define (ssax:warn port msg . other-msg) ...)) ...))
|
293
|
+
; because of the presence of (letrec-syntax ...), the begin form that
|
294
|
+
; is generated eventually is no longer at the top level! The begin
|
295
|
+
; form in Scheme is an overloading of two distinct forms: top-level
|
296
|
+
; begin and the other begin. The forms have different rules: for example,
|
297
|
+
; (begin (define x 1)) is OK for a top-level begin but not OK for
|
298
|
+
; the other begin. Some Scheme systems see the that the macro
|
299
|
+
; (run-test ...) expands into (letrec-syntax ...) and decide right there
|
300
|
+
; that any further (begin ...) forms are NOT top-level begin forms.
|
301
|
+
; The only way out is to make sure all our macros are top-level.
|
302
|
+
; The best approach <sigh> seems to be to make run-test one huge
|
303
|
+
; top-level macro.
|
304
|
+
|
305
|
+
|
306
|
+
(define-syntax run-test
|
307
|
+
(syntax-rules (define)
|
308
|
+
((run-test "scan-exp" (define vars body))
|
309
|
+
(define vars (run-test "scan-exp" body)))
|
310
|
+
((run-test "scan-exp" ?body)
|
311
|
+
(letrec-syntax
|
312
|
+
((scan-exp ; (scan-exp body k)
|
313
|
+
(syntax-rules (quote quasiquote !)
|
314
|
+
((scan-exp '() (k-head ! . args))
|
315
|
+
(k-head '() . args))
|
316
|
+
((scan-exp (quote (hd . tl)) k)
|
317
|
+
(scan-lit-lst (hd . tl) (do-wrap ! quasiquote k)))
|
318
|
+
((scan-exp (quasiquote (hd . tl)) k)
|
319
|
+
(scan-lit-lst (hd . tl) (do-wrap ! quasiquote k)))
|
320
|
+
((scan-exp (quote x) (k-head ! . args))
|
321
|
+
(k-head
|
322
|
+
(if (string? (quote x)) (string->symbol (quote x)) (quote x))
|
323
|
+
. args))
|
324
|
+
((scan-exp (hd . tl) k)
|
325
|
+
(scan-exp hd (do-tl ! scan-exp tl k)))
|
326
|
+
((scan-exp x (k-head ! . args))
|
327
|
+
(k-head x . args))))
|
328
|
+
(do-tl
|
329
|
+
(syntax-rules (!)
|
330
|
+
((do-tl processed-hd fn () (k-head ! . args))
|
331
|
+
(k-head (processed-hd) . args))
|
332
|
+
((do-tl processed-hd fn old-tl k)
|
333
|
+
(fn old-tl (do-cons ! processed-hd k)))))
|
334
|
+
(do-cons
|
335
|
+
(syntax-rules (!)
|
336
|
+
((do-cons processed-tl processed-hd (k-head ! . args))
|
337
|
+
(k-head (processed-hd . processed-tl) . args))))
|
338
|
+
(do-wrap
|
339
|
+
(syntax-rules (!)
|
340
|
+
((do-wrap val fn (k-head ! . args))
|
341
|
+
(k-head (fn val) . args))))
|
342
|
+
(do-finish
|
343
|
+
(syntax-rules ()
|
344
|
+
((do-finish new-body) new-body)))
|
345
|
+
|
346
|
+
(scan-lit-lst ; scan literal list
|
347
|
+
(syntax-rules (quote unquote unquote-splicing !)
|
348
|
+
((scan-lit-lst '() (k-head ! . args))
|
349
|
+
(k-head '() . args))
|
350
|
+
((scan-lit-lst (quote (hd . tl)) k)
|
351
|
+
(do-tl quote scan-lit-lst ((hd . tl)) k))
|
352
|
+
((scan-lit-lst (unquote x) k)
|
353
|
+
(scan-exp x (do-wrap ! unquote k)))
|
354
|
+
((scan-lit-lst (unquote-splicing x) k)
|
355
|
+
(scan-exp x (do-wrap ! unquote-splicing k)))
|
356
|
+
((scan-lit-lst (quote x) (k-head ! . args))
|
357
|
+
(k-head
|
358
|
+
,(if (string? (quote x)) (string->symbol (quote x)) (quote x))
|
359
|
+
. args))
|
360
|
+
((scan-lit-lst (hd . tl) k)
|
361
|
+
(scan-lit-lst hd (do-tl ! scan-lit-lst tl k)))
|
362
|
+
((scan-lit-lst x (k-head ! . args))
|
363
|
+
(k-head x . args))))
|
364
|
+
)
|
365
|
+
(scan-exp ?body (do-finish !))))
|
366
|
+
((run-test body ...)
|
367
|
+
(begin
|
368
|
+
(run-test "scan-exp" body) ...))
|
369
|
+
))
|
370
|
+
|
371
|
+
;========================================================================
|
372
|
+
; Data Types
|
373
|
+
|
374
|
+
; TAG-KIND
|
375
|
+
; a symbol 'START, 'END, 'PI, 'DECL, 'COMMENT, 'CDSECT
|
376
|
+
; or 'ENTITY-REF that identifies a markup token
|
377
|
+
|
378
|
+
; UNRES-NAME
|
379
|
+
; a name (called GI in the XML Recommendation) as given in an xml
|
380
|
+
; document for a markup token: start-tag, PI target, attribute name.
|
381
|
+
; If a GI is an NCName, UNRES-NAME is this NCName converted into
|
382
|
+
; a Scheme symbol. If a GI is a QName, UNRES-NAME is a pair of
|
383
|
+
; symbols: (PREFIX . LOCALPART)
|
384
|
+
|
385
|
+
; RES-NAME
|
386
|
+
; An expanded name, a resolved version of an UNRES-NAME.
|
387
|
+
; For an element or an attribute name with a non-empty namespace URI,
|
388
|
+
; RES-NAME is a pair of symbols, (URI-SYMB . LOCALPART).
|
389
|
+
; Otherwise, it's a single symbol.
|
390
|
+
|
391
|
+
; ELEM-CONTENT-MODEL
|
392
|
+
; A symbol:
|
393
|
+
; ANY - anything goes, expect an END tag.
|
394
|
+
; EMPTY-TAG - no content, and no END-tag is coming
|
395
|
+
; EMPTY - no content, expect the END-tag as the next token
|
396
|
+
; PCDATA - expect character data only, and no children elements
|
397
|
+
; MIXED
|
398
|
+
; ELEM-CONTENT
|
399
|
+
|
400
|
+
; URI-SYMB
|
401
|
+
; A symbol representing a namespace URI -- or other symbol chosen
|
402
|
+
; by the user to represent URI. In the former case,
|
403
|
+
; URI-SYMB is created by %-quoting of bad URI characters and
|
404
|
+
; converting the resulting string into a symbol.
|
405
|
+
|
406
|
+
; NAMESPACES
|
407
|
+
; A list representing namespaces in effect. An element of the list
|
408
|
+
; has one of the following forms:
|
409
|
+
; (PREFIX URI-SYMB . URI-SYMB) or
|
410
|
+
; (PREFIX USER-PREFIX . URI-SYMB)
|
411
|
+
; USER-PREFIX is a symbol chosen by the user
|
412
|
+
; to represent the URI.
|
413
|
+
; (#f USER-PREFIX . URI-SYMB)
|
414
|
+
; Specification of the user-chosen prefix and a URI-SYMBOL.
|
415
|
+
; (*DEFAULT* USER-PREFIX . URI-SYMB)
|
416
|
+
; Declaration of the default namespace
|
417
|
+
; (*DEFAULT* #f . #f)
|
418
|
+
; Un-declaration of the default namespace. This notation
|
419
|
+
; represents overriding of the previous declaration
|
420
|
+
; A NAMESPACES list may contain several elements for the same PREFIX.
|
421
|
+
; The one closest to the beginning of the list takes effect.
|
422
|
+
|
423
|
+
; ATTLIST
|
424
|
+
; An ordered collection of (NAME . VALUE) pairs, where NAME is
|
425
|
+
; a RES-NAME or an UNRES-NAME. The collection is an ADT
|
426
|
+
|
427
|
+
; STR-HANDLER
|
428
|
+
; A procedure of three arguments: STRING1 STRING2 SEED
|
429
|
+
; returning a new SEED
|
430
|
+
; The procedure is supposed to handle a chunk of character data
|
431
|
+
; STRING1 followed by a chunk of character data STRING2.
|
432
|
+
; STRING2 is a short string, often "\n" and even ""
|
433
|
+
|
434
|
+
; ENTITIES
|
435
|
+
; An assoc list of pairs:
|
436
|
+
; (named-entity-name . named-entity-body)
|
437
|
+
; where named-entity-name is a symbol under which the entity was
|
438
|
+
; declared, named-entity-body is either a string, or
|
439
|
+
; (for an external entity) a thunk that will return an
|
440
|
+
; input port (from which the entity can be read).
|
441
|
+
; named-entity-body may also be #f. This is an indication that a
|
442
|
+
; named-entity-name is currently being expanded. A reference to
|
443
|
+
; this named-entity-name will be an error: violation of the
|
444
|
+
; WFC nonrecursion.
|
445
|
+
;
|
446
|
+
; As an extension to the original SSAX, Guile allows a
|
447
|
+
; named-entity-name of *DEFAULT* to indicate a fallback procedure,
|
448
|
+
; called as (FALLBACK PORT NAME). The procedure should return a
|
449
|
+
; string.
|
450
|
+
|
451
|
+
; XML-TOKEN -- a record
|
452
|
+
|
453
|
+
; In Gambit, you can use the following declaration:
|
454
|
+
; (define-structure xml-token kind head)
|
455
|
+
; The following declaration is "standard" as it follows SRFI-9:
|
456
|
+
;;(define-record-type xml-token (make-xml-token kind head) xml-token?
|
457
|
+
;; (kind xml-token-kind)
|
458
|
+
;; (head xml-token-head) )
|
459
|
+
; No field mutators are declared as SSAX is a pure functional parser
|
460
|
+
;
|
461
|
+
; But to make the code more portable, we define xml-token simply as
|
462
|
+
; a pair. It suffices for us. Furthermore, xml-token-kind and xml-token-head
|
463
|
+
; can be defined as simple procedures. However, they are declared as
|
464
|
+
; macros below for efficiency.
|
465
|
+
|
466
|
+
(define (make-xml-token kind head) (cons kind head))
|
467
|
+
(define xml-token? pair?)
|
468
|
+
(define-syntax xml-token-kind
|
469
|
+
(syntax-rules () ((xml-token-kind token) (car token))))
|
470
|
+
(define-syntax xml-token-head
|
471
|
+
(syntax-rules () ((xml-token-head token) (cdr token))))
|
472
|
+
|
473
|
+
; (define-macro xml-token-kind (lambda (token) `(car ,token)))
|
474
|
+
; (define-macro xml-token-head (lambda (token) `(cdr ,token)))
|
475
|
+
|
476
|
+
; This record represents a markup, which is, according to the XML
|
477
|
+
; Recommendation, "takes the form of start-tags, end-tags, empty-element tags,
|
478
|
+
; entity references, character references, comments, CDATA section delimiters,
|
479
|
+
; document type declarations, and processing instructions."
|
480
|
+
;
|
481
|
+
; kind -- a TAG-KIND
|
482
|
+
; head -- an UNRES-NAME. For xml-tokens of kinds 'COMMENT and
|
483
|
+
; 'CDSECT, the head is #f
|
484
|
+
;
|
485
|
+
; For example,
|
486
|
+
; <P> => kind='START, head='P
|
487
|
+
; </P> => kind='END, head='P
|
488
|
+
; <BR/> => kind='EMPTY-EL, head='BR
|
489
|
+
; <!DOCTYPE OMF ...> => kind='DECL, head='DOCTYPE
|
490
|
+
; <?xml version="1.0"?> => kind='PI, head='xml
|
491
|
+
; &my-ent; => kind = 'ENTITY-REF, head='my-ent
|
492
|
+
;
|
493
|
+
; Character references are not represented by xml-tokens as these references
|
494
|
+
; are transparently resolved into the corresponding characters.
|
495
|
+
;
|
496
|
+
|
497
|
+
|
498
|
+
|
499
|
+
; XML-DECL -- a record
|
500
|
+
|
501
|
+
; The following is Gambit-specific, see below for a portable declaration
|
502
|
+
;(define-structure xml-decl elems entities notations)
|
503
|
+
|
504
|
+
; The record represents a datatype of an XML document: the list of
|
505
|
+
; declared elements and their attributes, declared notations, list of
|
506
|
+
; replacement strings or loading procedures for parsed general
|
507
|
+
; entities, etc. Normally an xml-decl record is created from a DTD or
|
508
|
+
; an XML Schema, although it can be created and filled in in many other
|
509
|
+
; ways (e.g., loaded from a file).
|
510
|
+
;
|
511
|
+
; elems: an (assoc) list of decl-elem or #f. The latter instructs
|
512
|
+
; the parser to do no validation of elements and attributes.
|
513
|
+
;
|
514
|
+
; decl-elem: declaration of one element:
|
515
|
+
; (elem-name elem-content decl-attrs)
|
516
|
+
; elem-name is an UNRES-NAME for the element.
|
517
|
+
; elem-content is an ELEM-CONTENT-MODEL.
|
518
|
+
; decl-attrs is an ATTLIST, of (ATTR-NAME . VALUE) associations
|
519
|
+
; !!!This element can declare a user procedure to handle parsing of an
|
520
|
+
; element (e.g., to do a custom validation, or to build a hash of
|
521
|
+
; IDs as they're encountered).
|
522
|
+
;
|
523
|
+
; decl-attr: an element of an ATTLIST, declaration of one attribute
|
524
|
+
; (attr-name content-type use-type default-value)
|
525
|
+
; attr-name is an UNRES-NAME for the declared attribute
|
526
|
+
; content-type is a symbol: CDATA, NMTOKEN, NMTOKENS, ...
|
527
|
+
; or a list of strings for the enumerated type.
|
528
|
+
; use-type is a symbol: REQUIRED, IMPLIED, FIXED
|
529
|
+
; default-value is a string for the default value, or #f if not given.
|
530
|
+
;
|
531
|
+
;
|
532
|
+
|
533
|
+
; see a function make-empty-xml-decl to make a XML declaration entry
|
534
|
+
; suitable for a non-validating parsing.
|
535
|
+
|
536
|
+
|
537
|
+
;-------------------------
|
538
|
+
; Utilities
|
539
|
+
|
540
|
+
; ssax:warn PORT MESSAGE SPECIALISING-MSG*
|
541
|
+
; to notify the user about warnings that are NOT errors but still
|
542
|
+
; may alert the user.
|
543
|
+
; Result is unspecified.
|
544
|
+
; We need to define the function to allow the self-tests to run.
|
545
|
+
; Normally the definition of ssax:warn is to be provided by the user.
|
546
|
+
(run-test
|
547
|
+
(define (ssax:warn port msg . other-msg)
|
548
|
+
(apply cerr (cons* nl "Warning: " msg other-msg)))
|
549
|
+
)
|
550
|
+
|
551
|
+
|
552
|
+
; parser-error PORT MESSAGE SPECIALISING-MSG*
|
553
|
+
; to let the user know of a syntax error or a violation of a
|
554
|
+
; well-formedness or validation constraint.
|
555
|
+
; Result is unspecified.
|
556
|
+
; We need to define the function to allow the self-tests to run.
|
557
|
+
; Normally the definition of parser-error is to be provided by the user.
|
558
|
+
(run-test
|
559
|
+
(define (parser-error port msg . specializing-msgs)
|
560
|
+
(apply error (cons msg specializing-msgs)))
|
561
|
+
)
|
562
|
+
|
563
|
+
; The following is a function that is often used in validation tests,
|
564
|
+
; to make sure that the computed result matches the expected one.
|
565
|
+
; This function is a standard equal? predicate with one exception.
|
566
|
+
; On Scheme systems where (string->symbol "A") and a symbol A
|
567
|
+
; are the same, equal_? is precisely equal?
|
568
|
+
; On other Scheme systems, we compare symbols disregarding their case.
|
569
|
+
; Since this function is used only in tests, we don't have to
|
570
|
+
; strive to make it efficient.
|
571
|
+
(run-test
|
572
|
+
(define (equal_? e1 e2)
|
573
|
+
(if (eq? 'A (string->symbol "A")) (equal? e1 e2)
|
574
|
+
(cond
|
575
|
+
((symbol? e1)
|
576
|
+
(and (symbol? e2)
|
577
|
+
(string-ci=? (symbol->string e1) (symbol->string e2))))
|
578
|
+
((pair? e1)
|
579
|
+
(and (pair? e2)
|
580
|
+
(equal_? (car e1) (car e2)) (equal_? (cdr e1) (cdr e2))))
|
581
|
+
((vector? e1)
|
582
|
+
(and (vector? e2) (equal_? (vector->list e1) (vector->list e2))))
|
583
|
+
(else
|
584
|
+
(equal? e1 e2)))))
|
585
|
+
)
|
586
|
+
|
587
|
+
; The following function, which is often used in validation tests,
|
588
|
+
; lets us conveniently enter newline, CR and tab characters in a character
|
589
|
+
; string.
|
590
|
+
; unesc-string: ESC-STRING -> STRING
|
591
|
+
; where ESC-STRING is a character string that may contain
|
592
|
+
; %n -- for #\newline
|
593
|
+
; %r -- for #\return
|
594
|
+
; %t -- for #\tab
|
595
|
+
; %% -- for #\%
|
596
|
+
;
|
597
|
+
; The result of unesc-string is a character string with all %-combinations
|
598
|
+
; above replaced with their character equivalents
|
599
|
+
|
600
|
+
(run-test
|
601
|
+
(define (unesc-string str)
|
602
|
+
(call-with-input-string str
|
603
|
+
(lambda (port)
|
604
|
+
(let loop ((frags '()))
|
605
|
+
(let* ((token (next-token '() '(#\% *eof*) "unesc-string" port))
|
606
|
+
(cterm (read-char port))
|
607
|
+
(frags (cons token frags)))
|
608
|
+
(if (eof-object? cterm) (string-concatenate-reverse/shared frags)
|
609
|
+
(let ((cchar (read-char port))) ; char after #\%
|
610
|
+
(if (eof-object? cchar)
|
611
|
+
(error "unexpected EOF after reading % in unesc-string:" str)
|
612
|
+
(loop
|
613
|
+
(cons
|
614
|
+
(case cchar
|
615
|
+
((#\n) (string #\newline))
|
616
|
+
((#\r) (string char-return))
|
617
|
+
((#\t) (string char-tab))
|
618
|
+
((#\%) "%")
|
619
|
+
(else (error "bad %-char in unesc-string:" cchar)))
|
620
|
+
frags))))))))))
|
621
|
+
)
|
622
|
+
|
623
|
+
|
624
|
+
; Test if a string is made of only whitespace
|
625
|
+
; An empty string is considered made of whitespace as well
|
626
|
+
(define (string-whitespace? str)
|
627
|
+
(let ((len (string-length str)))
|
628
|
+
(cond
|
629
|
+
((zero? len) #t)
|
630
|
+
((= 1 len) (char-whitespace? (string-ref str 0)))
|
631
|
+
((= 2 len) (and (char-whitespace? (string-ref str 0))
|
632
|
+
(char-whitespace? (string-ref str 1))))
|
633
|
+
(else
|
634
|
+
(let loop ((i 0))
|
635
|
+
(or (>= i len)
|
636
|
+
(and (char-whitespace? (string-ref str i))
|
637
|
+
(loop (inc i)))))))))
|
638
|
+
|
639
|
+
; Find val in alist
|
640
|
+
; Return (values found-el remaining-alist) or
|
641
|
+
; (values #f alist)
|
642
|
+
|
643
|
+
(define (assq-values val alist)
|
644
|
+
(let loop ((alist alist) (scanned '()))
|
645
|
+
(cond
|
646
|
+
((null? alist) (values #f scanned))
|
647
|
+
((equal? val (caar alist))
|
648
|
+
(values (car alist) (append scanned (cdr alist))))
|
649
|
+
(else
|
650
|
+
(loop (cdr alist) (cons (car alist) scanned))))))
|
651
|
+
|
652
|
+
; From SRFI-1
|
653
|
+
(define (fold-right kons knil lis1)
|
654
|
+
(let recur ((lis lis1))
|
655
|
+
(if (null? lis) knil
|
656
|
+
(let ((head (car lis)))
|
657
|
+
(kons head (recur (cdr lis)))))))
|
658
|
+
|
659
|
+
; Left fold combinator for a single list
|
660
|
+
(define (fold kons knil lis1)
|
661
|
+
(let lp ((lis lis1) (ans knil))
|
662
|
+
(if (null? lis) ans
|
663
|
+
(lp (cdr lis) (kons (car lis) ans)))))
|
664
|
+
|
665
|
+
|
666
|
+
|
667
|
+
;========================================================================
|
668
|
+
; Lower-level parsers and scanners
|
669
|
+
;
|
670
|
+
; They deal with primitive lexical units (Names, whitespaces, tags)
|
671
|
+
; and with pieces of more generic productions. Most of these parsers
|
672
|
+
; must be called in appropriate context. For example, ssax:complete-start-tag
|
673
|
+
; must be called only when the start-tag has been detected and its GI
|
674
|
+
; has been read.
|
675
|
+
|
676
|
+
;------------------------------------------------------------------------
|
677
|
+
; Low-level parsing code
|
678
|
+
|
679
|
+
; Skip the S (whitespace) production as defined by
|
680
|
+
; [3] S ::= (#x20 | #x9 | #xD | #xA)
|
681
|
+
; The procedure returns the first not-whitespace character it
|
682
|
+
; encounters while scanning the PORT. This character is left
|
683
|
+
; on the input stream.
|
684
|
+
|
685
|
+
(define ssax:S-chars (map ascii->char '(32 10 9 13)))
|
686
|
+
|
687
|
+
(define (ssax:skip-S port)
|
688
|
+
(skip-while ssax:S-chars port))
|
689
|
+
|
690
|
+
|
691
|
+
; Read a Name lexem and return it as string
|
692
|
+
; [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':'
|
693
|
+
; | CombiningChar | Extender
|
694
|
+
; [5] Name ::= (Letter | '_' | ':') (NameChar)*
|
695
|
+
;
|
696
|
+
; This code supports the XML Namespace Recommendation REC-xml-names,
|
697
|
+
; which modifies the above productions as follows:
|
698
|
+
;
|
699
|
+
; [4] NCNameChar ::= Letter | Digit | '.' | '-' | '_'
|
700
|
+
; | CombiningChar | Extender
|
701
|
+
; [5] NCName ::= (Letter | '_') (NCNameChar)*
|
702
|
+
; As the Rec-xml-names says,
|
703
|
+
; "An XML document conforms to this specification if all other tokens
|
704
|
+
; [other than element types and attribute names] in the document which
|
705
|
+
; are required, for XML conformance, to match the XML production for
|
706
|
+
; Name, match this specification's production for NCName."
|
707
|
+
; Element types and attribute names must match the production QName,
|
708
|
+
; defined below.
|
709
|
+
|
710
|
+
; Check to see if a-char may start a NCName
|
711
|
+
(define (ssax:ncname-starting-char? a-char)
|
712
|
+
(and (char? a-char)
|
713
|
+
(or
|
714
|
+
(char-alphabetic? a-char)
|
715
|
+
(char=? #\_ a-char))))
|
716
|
+
|
717
|
+
|
718
|
+
; Read a NCName starting from the current position in the PORT and
|
719
|
+
; return it as a symbol.
|
720
|
+
(define (ssax:read-NCName port)
|
721
|
+
(let ((first-char (peek-char port)))
|
722
|
+
(or (ssax:ncname-starting-char? first-char)
|
723
|
+
(parser-error port "XMLNS [4] for '" first-char "'")))
|
724
|
+
(string->symbol
|
725
|
+
(next-token-of
|
726
|
+
(lambda (c)
|
727
|
+
(cond
|
728
|
+
((eof-object? c) #f)
|
729
|
+
((char-alphabetic? c) c)
|
730
|
+
((string-index "0123456789.-_" c) c)
|
731
|
+
(else #f)))
|
732
|
+
port)))
|
733
|
+
|
734
|
+
; Read a (namespace-) Qualified Name, QName, from the current
|
735
|
+
; position in the PORT.
|
736
|
+
; From REC-xml-names:
|
737
|
+
; [6] QName ::= (Prefix ':')? LocalPart
|
738
|
+
; [7] Prefix ::= NCName
|
739
|
+
; [8] LocalPart ::= NCName
|
740
|
+
; Return: an UNRES-NAME
|
741
|
+
(define (ssax:read-QName port)
|
742
|
+
(let ((prefix-or-localpart (ssax:read-NCName port)))
|
743
|
+
(case (peek-char port)
|
744
|
+
((#\:) ; prefix was given after all
|
745
|
+
(read-char port) ; consume the colon
|
746
|
+
(cons prefix-or-localpart (ssax:read-NCName port)))
|
747
|
+
(else prefix-or-localpart) ; Prefix was omitted
|
748
|
+
)))
|
749
|
+
|
750
|
+
; The prefix of the pre-defined XML namespace
|
751
|
+
(define ssax:Prefix-XML (string->symbol "xml"))
|
752
|
+
|
753
|
+
(run-test
|
754
|
+
(assert (eq? '_
|
755
|
+
(call-with-input-string "_" ssax:read-NCName)))
|
756
|
+
(assert (eq? '_
|
757
|
+
(call-with-input-string "_" ssax:read-QName)))
|
758
|
+
(assert (eq? (string->symbol "_abc_")
|
759
|
+
(call-with-input-string "_abc_;" ssax:read-NCName)))
|
760
|
+
(assert (eq? (string->symbol "_abc_")
|
761
|
+
(call-with-input-string "_abc_;" ssax:read-QName)))
|
762
|
+
(assert (eq? (string->symbol "_a.b")
|
763
|
+
(call-with-input-string "_a.b " ssax:read-QName)))
|
764
|
+
(assert (equal? (cons (string->symbol "_a.b") (string->symbol "d.1-ef-"))
|
765
|
+
(call-with-input-string "_a.b:d.1-ef-;" ssax:read-QName)))
|
766
|
+
(assert (equal? (cons (string->symbol "a") (string->symbol "b"))
|
767
|
+
(call-with-input-string "a:b:c" ssax:read-QName)))
|
768
|
+
|
769
|
+
(assert (failed? (call-with-input-string ":abc" ssax:read-NCName)))
|
770
|
+
(assert (failed? (call-with-input-string "1:bc" ssax:read-NCName)))
|
771
|
+
)
|
772
|
+
|
773
|
+
; Compare one RES-NAME or an UNRES-NAME with the other.
|
774
|
+
; Return a symbol '<, '>, or '= depending on the result of
|
775
|
+
; the comparison.
|
776
|
+
; Names without PREFIX are always smaller than those with the PREFIX.
|
777
|
+
(define name-compare
|
778
|
+
(letrec ((symbol-compare
|
779
|
+
(lambda (symb1 symb2)
|
780
|
+
(cond
|
781
|
+
((eq? symb1 symb2) '=)
|
782
|
+
((string<? (symbol->string symb1) (symbol->string symb2))
|
783
|
+
'<)
|
784
|
+
(else '>)))))
|
785
|
+
(lambda (name1 name2)
|
786
|
+
(cond
|
787
|
+
((symbol? name1) (if (symbol? name2) (symbol-compare name1 name2)
|
788
|
+
'<))
|
789
|
+
((symbol? name2) '>)
|
790
|
+
((eq? name2 ssax:largest-unres-name) '<)
|
791
|
+
((eq? name1 ssax:largest-unres-name) '>)
|
792
|
+
((eq? (car name1) (car name2)) ; prefixes the same
|
793
|
+
(symbol-compare (cdr name1) (cdr name2)))
|
794
|
+
(else (symbol-compare (car name1) (car name2)))))))
|
795
|
+
|
796
|
+
; An UNRES-NAME that is postulated to be larger than anything that can occur in
|
797
|
+
; a well-formed XML document.
|
798
|
+
; name-compare enforces this postulate.
|
799
|
+
(define ssax:largest-unres-name (cons
|
800
|
+
(string->symbol "#LARGEST-SYMBOL")
|
801
|
+
(string->symbol "#LARGEST-SYMBOL")))
|
802
|
+
|
803
|
+
(run-test
|
804
|
+
(assert (eq? '= (name-compare 'ABC 'ABC)))
|
805
|
+
(assert (eq? '< (name-compare 'ABC 'ABCD)))
|
806
|
+
(assert (eq? '> (name-compare 'XB 'ABCD)))
|
807
|
+
(assert (eq? '> (name-compare '(HTML . PRE) 'PRE)))
|
808
|
+
(assert (eq? '< (name-compare 'HTML '(HTML . PRE))))
|
809
|
+
(assert (eq? '= (name-compare '(HTML . PRE) '(HTML . PRE))))
|
810
|
+
(assert (eq? '< (name-compare '(HTML . PRE) '(XML . PRE))))
|
811
|
+
(assert (eq? '> (name-compare '(HTML . PRE) '(HTML . P))))
|
812
|
+
(assert (eq? '< (name-compare '(HTML . PRE) ssax:largest-unres-name)))
|
813
|
+
(assert (eq? '< (name-compare '(ZZZZ . ZZZ) ssax:largest-unres-name)))
|
814
|
+
(assert (eq? '> (name-compare ssax:largest-unres-name '(ZZZZ . ZZZ) )))
|
815
|
+
)
|
816
|
+
|
817
|
+
|
818
|
+
|
819
|
+
; procedure: ssax:read-markup-token PORT
|
820
|
+
; This procedure starts parsing of a markup token. The current position
|
821
|
+
; in the stream must be #\<. This procedure scans enough of the input stream
|
822
|
+
; to figure out what kind of a markup token it is seeing. The procedure returns
|
823
|
+
; an xml-token structure describing the token. Note, generally reading
|
824
|
+
; of the current markup is not finished! In particular, no attributes of
|
825
|
+
; the start-tag token are scanned.
|
826
|
+
;
|
827
|
+
; Here's a detailed break out of the return values and the position in the PORT
|
828
|
+
; when that particular value is returned:
|
829
|
+
; PI-token: only PI-target is read.
|
830
|
+
; To finish the Processing Instruction and disregard it,
|
831
|
+
; call ssax:skip-pi. ssax:read-attributes may be useful
|
832
|
+
; as well (for PIs whose content is attribute-value
|
833
|
+
; pairs)
|
834
|
+
; END-token: The end tag is read completely; the current position
|
835
|
+
; is right after the terminating #\> character.
|
836
|
+
; COMMENT is read and skipped completely. The current position
|
837
|
+
; is right after "-->" that terminates the comment.
|
838
|
+
; CDSECT The current position is right after "<!CDATA["
|
839
|
+
; Use ssax:read-cdata-body to read the rest.
|
840
|
+
; DECL We have read the keyword (the one that follows "<!")
|
841
|
+
; identifying this declaration markup. The current
|
842
|
+
; position is after the keyword (usually a
|
843
|
+
; whitespace character)
|
844
|
+
;
|
845
|
+
; START-token We have read the keyword (GI) of this start tag.
|
846
|
+
; No attributes are scanned yet. We don't know if this
|
847
|
+
; tag has an empty content either.
|
848
|
+
; Use ssax:complete-start-tag to finish parsing of
|
849
|
+
; the token.
|
850
|
+
|
851
|
+
(define ssax:read-markup-token ; procedure ssax:read-markup-token port
|
852
|
+
(let ()
|
853
|
+
; we have read "<!-". Skip through the rest of the comment
|
854
|
+
; Return the 'COMMENT token as an indication we saw a comment
|
855
|
+
; and skipped it.
|
856
|
+
(define (skip-comment port)
|
857
|
+
(assert-curr-char '(#\-) "XML [15], second dash" port)
|
858
|
+
(if (not (find-string-from-port? "-->" port))
|
859
|
+
(parser-error port "XML [15], no -->"))
|
860
|
+
(make-xml-token 'COMMENT #f))
|
861
|
+
|
862
|
+
; we have read "<![" that must begin a CDATA section
|
863
|
+
(define (read-cdata port)
|
864
|
+
(assert (string=? "CDATA[" (read-string 6 port)))
|
865
|
+
(make-xml-token 'CDSECT #f))
|
866
|
+
|
867
|
+
(lambda (port)
|
868
|
+
(assert-curr-char '(#\<) "start of the token" port)
|
869
|
+
(case (peek-char port)
|
870
|
+
((#\/) (read-char port)
|
871
|
+
(begin0 (make-xml-token 'END (ssax:read-QName port))
|
872
|
+
(ssax:skip-S port)
|
873
|
+
(assert-curr-char '(#\>) "XML [42]" port)))
|
874
|
+
((#\?) (read-char port) (make-xml-token 'PI (ssax:read-NCName port)))
|
875
|
+
((#\!)
|
876
|
+
(case (peek-next-char port)
|
877
|
+
((#\-) (read-char port) (skip-comment port))
|
878
|
+
((#\[) (read-char port) (read-cdata port))
|
879
|
+
(else (make-xml-token 'DECL (ssax:read-NCName port)))))
|
880
|
+
(else (make-xml-token 'START (ssax:read-QName port)))))
|
881
|
+
))
|
882
|
+
|
883
|
+
|
884
|
+
; The current position is inside a PI. Skip till the rest of the PI
|
885
|
+
(define (ssax:skip-pi port)
|
886
|
+
(if (not (find-string-from-port? "?>" port))
|
887
|
+
(parser-error port "Failed to find ?> terminating the PI")))
|
888
|
+
|
889
|
+
|
890
|
+
; The current position is right after reading the PITarget. We read the
|
891
|
+
; body of PI and return is as a string. The port will point to the
|
892
|
+
; character right after '?>' combination that terminates PI.
|
893
|
+
; [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
|
894
|
+
|
895
|
+
(define (ssax:read-pi-body-as-string port)
|
896
|
+
(ssax:skip-S port) ; skip WS after the PI target name
|
897
|
+
(string-concatenate/shared
|
898
|
+
(let loop ()
|
899
|
+
(let ((pi-fragment
|
900
|
+
(next-token '() '(#\?) "reading PI content" port)))
|
901
|
+
(if (eqv? #\> (peek-next-char port))
|
902
|
+
(begin
|
903
|
+
(read-char port)
|
904
|
+
(cons pi-fragment '()))
|
905
|
+
(cons* pi-fragment "?" (loop)))))))
|
906
|
+
|
907
|
+
(run-test
|
908
|
+
(assert (equal? "p1 content "
|
909
|
+
(call-with-input-string "<?pi1 p1 content ?>"
|
910
|
+
(lambda (port)
|
911
|
+
(ssax:read-markup-token port)
|
912
|
+
(ssax:read-pi-body-as-string port)))))
|
913
|
+
(assert (equal? "pi2? content? ?"
|
914
|
+
(call-with-input-string "<?pi2 pi2? content? ??>"
|
915
|
+
(lambda (port)
|
916
|
+
(ssax:read-markup-token port)
|
917
|
+
(ssax:read-pi-body-as-string port)))))
|
918
|
+
)
|
919
|
+
|
920
|
+
;(define (ssax:read-pi-body-as-name-values port)
|
921
|
+
|
922
|
+
; The current pos in the port is inside an internal DTD subset
|
923
|
+
; (e.g., after reading #\[ that begins an internal DTD subset)
|
924
|
+
; Skip until the "]>" combination that terminates this DTD
|
925
|
+
(define (ssax:skip-internal-dtd port)
|
926
|
+
(if (not (find-string-from-port? "]>" port))
|
927
|
+
(parser-error port
|
928
|
+
"Failed to find ]> terminating the internal DTD subset")))
|
929
|
+
|
930
|
+
|
931
|
+
; procedure+: ssax:read-cdata-body PORT STR-HANDLER SEED
|
932
|
+
;
|
933
|
+
; This procedure must be called after we have read a string "<![CDATA["
|
934
|
+
; that begins a CDATA section. The current position must be the first
|
935
|
+
; position of the CDATA body. This function reads _lines_ of the CDATA
|
936
|
+
; body and passes them to a STR-HANDLER, a character data consumer.
|
937
|
+
;
|
938
|
+
; The str-handler is a STR-HANDLER, a procedure STRING1 STRING2 SEED.
|
939
|
+
; The first STRING1 argument to STR-HANDLER never contains a newline.
|
940
|
+
; The second STRING2 argument often will. On the first invocation of
|
941
|
+
; the STR-HANDLER, the seed is the one passed to ssax:read-cdata-body
|
942
|
+
; as the third argument. The result of this first invocation will be
|
943
|
+
; passed as the seed argument to the second invocation of the line
|
944
|
+
; consumer, and so on. The result of the last invocation of the
|
945
|
+
; STR-HANDLER is returned by the ssax:read-cdata-body. Note a
|
946
|
+
; similarity to the fundamental 'fold' iterator.
|
947
|
+
;
|
948
|
+
; Within a CDATA section all characters are taken at their face value,
|
949
|
+
; with only three exceptions:
|
950
|
+
; CR, LF, and CRLF are treated as line delimiters, and passed
|
951
|
+
; as a single #\newline to the STR-HANDLER
|
952
|
+
; "]]>" combination is the end of the CDATA section.
|
953
|
+
; > is treated as an embedded #\> character
|
954
|
+
; Note, < and & are not specially recognized (and are not expanded)!
|
955
|
+
|
956
|
+
(define ssax:read-cdata-body
|
957
|
+
(let ((cdata-delimiters (list char-return #\newline #\] #\&)))
|
958
|
+
|
959
|
+
(lambda (port str-handler seed)
|
960
|
+
(let loop ((seed seed))
|
961
|
+
(let ((fragment (next-token '() cdata-delimiters
|
962
|
+
"reading CDATA" port)))
|
963
|
+
; that is, we're reading the char after the 'fragment'
|
964
|
+
(case (read-char port)
|
965
|
+
((#\newline) (loop (str-handler fragment nl seed)))
|
966
|
+
((#\])
|
967
|
+
(if (not (eqv? (peek-char port) #\]))
|
968
|
+
(loop (str-handler fragment "]" seed))
|
969
|
+
(let check-after-second-braket
|
970
|
+
((seed (if (string-null? fragment) seed
|
971
|
+
(str-handler fragment "" seed))))
|
972
|
+
(case (peek-next-char port) ; after the second bracket
|
973
|
+
((#\>) (read-char port) seed) ; we have read "]]>"
|
974
|
+
((#\]) (check-after-second-braket
|
975
|
+
(str-handler "]" "" seed)))
|
976
|
+
(else (loop (str-handler "]]" "" seed)))))))
|
977
|
+
((#\&) ; Note that #\& within CDATA may stand for itself
|
978
|
+
(let ((ent-ref ; it does not have to start an entity ref
|
979
|
+
(next-token-of (lambda (c)
|
980
|
+
(and (not (eof-object? c)) (char-alphabetic? c) c)) port)))
|
981
|
+
(cond ; ">" is to be replaced with #\>
|
982
|
+
((and (string=? "gt" ent-ref) (eqv? (peek-char port) #\;))
|
983
|
+
(read-char port)
|
984
|
+
(loop (str-handler fragment ">" seed)))
|
985
|
+
(else
|
986
|
+
(loop
|
987
|
+
(str-handler ent-ref ""
|
988
|
+
(str-handler fragment "&" seed)))))))
|
989
|
+
(else ; Must be CR: if the next char is #\newline, skip it
|
990
|
+
(if (eqv? (peek-char port) #\newline) (read-char port))
|
991
|
+
(loop (str-handler fragment nl seed)))
|
992
|
+
))))))
|
993
|
+
|
994
|
+
; a few lines of validation code
|
995
|
+
(run-test (letrec
|
996
|
+
((consumer (lambda (fragment foll-fragment seed)
|
997
|
+
(cons* (if (equal? foll-fragment (string #\newline))
|
998
|
+
" NL" foll-fragment) fragment seed)))
|
999
|
+
(test (lambda (str expected-result)
|
1000
|
+
(newline) (display "body: ") (write str)
|
1001
|
+
(newline) (display "Result: ")
|
1002
|
+
(let ((result
|
1003
|
+
(reverse
|
1004
|
+
(call-with-input-string (unesc-string str)
|
1005
|
+
(lambda (port) (ssax:read-cdata-body port consumer '()))
|
1006
|
+
))))
|
1007
|
+
(write result)
|
1008
|
+
(assert (equal? result expected-result)))))
|
1009
|
+
)
|
1010
|
+
(test "]]>" '())
|
1011
|
+
(test "abcd]]>" '("abcd" ""))
|
1012
|
+
(test "abcd]]]>" '("abcd" "" "]" ""))
|
1013
|
+
(test "abcd]]]]>" '("abcd" "" "]" "" "]" ""))
|
1014
|
+
(test "abcd]]]]]>" '("abcd" "" "]" "" "]" "" "]" ""))
|
1015
|
+
(test "abcd]]]a]]>" '("abcd" "" "]" "" "]]" "" "a" ""))
|
1016
|
+
(test "abc%r%ndef%n]]>" '("abc" " NL" "def" " NL"))
|
1017
|
+
(test "%r%n%r%n]]>" '("" " NL" "" " NL"))
|
1018
|
+
(test "%r%n%r%na]]>" '("" " NL" "" " NL" "a" ""))
|
1019
|
+
(test "%r%r%r%na]]>" '("" " NL" "" " NL" "" " NL" "a" ""))
|
1020
|
+
(test "abc&!!!]]>" '("abc" "&" "" "" "!!!" ""))
|
1021
|
+
(test "abc]]>>&]]]>and]]>"
|
1022
|
+
'("abc" "" "]]" "" "" ">" "" "&" "gt" "" "" "&" "amp" "" ";" "" "]" ""
|
1023
|
+
"]]" "" "" ">" "and" ""))
|
1024
|
+
))
|
1025
|
+
|
1026
|
+
|
1027
|
+
; procedure+: ssax:read-char-ref PORT
|
1028
|
+
;
|
1029
|
+
; [66] CharRef ::= '&#' [0-9]+ ';'
|
1030
|
+
; | '&#x' [0-9a-fA-F]+ ';'
|
1031
|
+
;
|
1032
|
+
; This procedure must be called after we we have read "&#"
|
1033
|
+
; that introduces a char reference.
|
1034
|
+
; The procedure reads this reference and returns the corresponding char
|
1035
|
+
; The current position in PORT will be after ";" that terminates
|
1036
|
+
; the char reference
|
1037
|
+
; Faults detected:
|
1038
|
+
; WFC: XML-Spec.html#wf-Legalchar
|
1039
|
+
;
|
1040
|
+
; According to Section "4.1 Character and Entity References"
|
1041
|
+
; of the XML Recommendation:
|
1042
|
+
; "[Definition: A character reference refers to a specific character
|
1043
|
+
; in the ISO/IEC 10646 character set, for example one not directly
|
1044
|
+
; accessible from available input devices.]"
|
1045
|
+
; Therefore, we use a ucscode->string function to convert a character
|
1046
|
+
; code into the character -- *regardless* of the current character
|
1047
|
+
; encoding of the input stream.
|
1048
|
+
|
1049
|
+
(define (ssax:read-char-ref port)
|
1050
|
+
(let* ((base
|
1051
|
+
(cond ((eqv? (peek-char port) #\x) (read-char port) 16)
|
1052
|
+
(else 10)))
|
1053
|
+
(name (next-token '() '(#\;) "XML [66]" port))
|
1054
|
+
(char-code (string->number name base)))
|
1055
|
+
(read-char port) ; read the terminating #\; char
|
1056
|
+
(if (integer? char-code) (ucscode->string char-code)
|
1057
|
+
(parser-error port "[wf-Legalchar] broken for '" name "'"))))
|
1058
|
+
|
1059
|
+
|
1060
|
+
; procedure+: ssax:handle-parsed-entity PORT NAME ENTITIES
|
1061
|
+
; CONTENT-HANDLER STR-HANDLER SEED
|
1062
|
+
;
|
1063
|
+
; Expand and handle a parsed-entity reference
|
1064
|
+
; port - a PORT
|
1065
|
+
; name - the name of the parsed entity to expand, a symbol
|
1066
|
+
; entities - see ENTITIES
|
1067
|
+
; content-handler -- procedure PORT ENTITIES SEED
|
1068
|
+
; that is supposed to return a SEED
|
1069
|
+
; str-handler - a STR-HANDLER. It is called if the entity in question
|
1070
|
+
; turns out to be a pre-declared entity
|
1071
|
+
;
|
1072
|
+
; The result is the one returned by CONTENT-HANDLER or STR-HANDLER
|
1073
|
+
; Faults detected:
|
1074
|
+
; WFC: XML-Spec.html#wf-entdeclared
|
1075
|
+
; WFC: XML-Spec.html#norecursion
|
1076
|
+
|
1077
|
+
(define ssax:predefined-parsed-entities
|
1078
|
+
`(
|
1079
|
+
(,(string->symbol "amp") . "&")
|
1080
|
+
(,(string->symbol "lt") . "<")
|
1081
|
+
(,(string->symbol "gt") . ">")
|
1082
|
+
(,(string->symbol "apos") . "'")
|
1083
|
+
(,(string->symbol "quot") . "\"")))
|
1084
|
+
|
1085
|
+
(define (ssax:handle-parsed-entity port name entities
|
1086
|
+
content-handler str-handler seed)
|
1087
|
+
(cond ; First we check the list of the declared entities
|
1088
|
+
((assq name entities) =>
|
1089
|
+
(lambda (decl-entity)
|
1090
|
+
(let ((ent-body (cdr decl-entity)) ; mark the list to prevent recursion
|
1091
|
+
(new-entities (cons (cons name #f) entities)))
|
1092
|
+
(cond
|
1093
|
+
((string? ent-body)
|
1094
|
+
(call-with-input-string ent-body
|
1095
|
+
(lambda (port) (content-handler port new-entities seed))))
|
1096
|
+
((procedure? ent-body)
|
1097
|
+
(let ((port (ent-body)))
|
1098
|
+
(begin0
|
1099
|
+
(content-handler port new-entities seed)
|
1100
|
+
(close-input-port port))))
|
1101
|
+
(else
|
1102
|
+
(parser-error port "[norecursion] broken for " name))))))
|
1103
|
+
((assq name ssax:predefined-parsed-entities)
|
1104
|
+
=> (lambda (decl-entity)
|
1105
|
+
(str-handler (cdr decl-entity) "" seed)))
|
1106
|
+
((assq '*DEFAULT* entities) =>
|
1107
|
+
(lambda (decl-entity)
|
1108
|
+
(let ((fallback (cdr decl-entity))
|
1109
|
+
(new-entities (cons (cons name #f) entities)))
|
1110
|
+
(cond
|
1111
|
+
((procedure? fallback)
|
1112
|
+
(call-with-input-string (fallback port name)
|
1113
|
+
(lambda (port) (content-handler port new-entities seed))))
|
1114
|
+
(else
|
1115
|
+
(parser-error port "[norecursion] broken for " name))))))
|
1116
|
+
(else (parser-error port "[wf-entdeclared] broken for " name))))
|
1117
|
+
|
1118
|
+
|
1119
|
+
|
1120
|
+
; The ATTLIST Abstract Data Type
|
1121
|
+
; Currently is implemented as an assoc list sorted in the ascending
|
1122
|
+
; order of NAMES.
|
1123
|
+
|
1124
|
+
(define (make-empty-attlist) '())
|
1125
|
+
|
1126
|
+
; Add a name-value pair to the existing attlist preserving the order
|
1127
|
+
; Return the new list, in the sorted ascending order.
|
1128
|
+
; Return #f if a pair with the same name already exists in the attlist
|
1129
|
+
|
1130
|
+
(define (attlist-add attlist name-value)
|
1131
|
+
(if (null? attlist) (cons name-value attlist)
|
1132
|
+
(case (name-compare (car name-value) (caar attlist))
|
1133
|
+
((=) #f)
|
1134
|
+
((<) (cons name-value attlist))
|
1135
|
+
(else (cons (car attlist) (attlist-add (cdr attlist) name-value)))
|
1136
|
+
)))
|
1137
|
+
|
1138
|
+
(define attlist-null? null?)
|
1139
|
+
|
1140
|
+
; Given an non-null attlist, return a pair of values: the top and the rest
|
1141
|
+
(define (attlist-remove-top attlist)
|
1142
|
+
(values (car attlist) (cdr attlist)))
|
1143
|
+
|
1144
|
+
(define (attlist->alist attlist) attlist)
|
1145
|
+
(define attlist-fold fold)
|
1146
|
+
|
1147
|
+
; procedure+: ssax:read-attributes PORT ENTITIES
|
1148
|
+
;
|
1149
|
+
; This procedure reads and parses a production Attribute*
|
1150
|
+
; [41] Attribute ::= Name Eq AttValue
|
1151
|
+
; [10] AttValue ::= '"' ([^<&"] | Reference)* '"'
|
1152
|
+
; | "'" ([^<&'] | Reference)* "'"
|
1153
|
+
; [25] Eq ::= S? '=' S?
|
1154
|
+
;
|
1155
|
+
;
|
1156
|
+
; The procedure returns an ATTLIST, of Name (as UNRES-NAME), Value (as string)
|
1157
|
+
; pairs. The current character on the PORT is a non-whitespace character
|
1158
|
+
; that is not an ncname-starting character.
|
1159
|
+
;
|
1160
|
+
; Note the following rules to keep in mind when reading an 'AttValue'
|
1161
|
+
; "Before the value of an attribute is passed to the application
|
1162
|
+
; or checked for validity, the XML processor must normalize it as follows:
|
1163
|
+
; - a character reference is processed by appending the referenced
|
1164
|
+
; character to the attribute value
|
1165
|
+
; - an entity reference is processed by recursively processing the
|
1166
|
+
; replacement text of the entity [see ENTITIES]
|
1167
|
+
; [named entities amp lt gt quot apos are assumed pre-declared]
|
1168
|
+
; - a whitespace character (#x20, #xD, #xA, #x9) is processed by appending #x20
|
1169
|
+
; to the normalized value, except that only a single #x20 is appended for a
|
1170
|
+
; "#xD#xA" sequence that is part of an external parsed entity or the
|
1171
|
+
; literal entity value of an internal parsed entity
|
1172
|
+
; - other characters are processed by appending them to the normalized value "
|
1173
|
+
;
|
1174
|
+
;
|
1175
|
+
; Faults detected:
|
1176
|
+
; WFC: XML-Spec.html#CleanAttrVals
|
1177
|
+
; WFC: XML-Spec.html#uniqattspec
|
1178
|
+
|
1179
|
+
(define ssax:read-attributes ; ssax:read-attributes port entities
|
1180
|
+
(let ((value-delimeters (append ssax:S-chars '(#\< #\&))))
|
1181
|
+
; Read the AttValue from the PORT up to the delimiter
|
1182
|
+
; (which can be a single or double-quote character,
|
1183
|
+
; or even a symbol *eof*)
|
1184
|
+
; 'prev-fragments' is the list of string fragments, accumulated
|
1185
|
+
; so far, in reverse order.
|
1186
|
+
; Return the list of fragments with newly read fragments
|
1187
|
+
; prepended.
|
1188
|
+
(define (read-attrib-value delimiter port entities prev-fragments)
|
1189
|
+
(let* ((new-fragments
|
1190
|
+
(cons (next-token '() (cons delimiter value-delimeters)
|
1191
|
+
"XML [10]" port)
|
1192
|
+
prev-fragments))
|
1193
|
+
(cterm (read-char port)))
|
1194
|
+
(cond
|
1195
|
+
((or (eof-object? cterm) (eqv? cterm delimiter))
|
1196
|
+
new-fragments)
|
1197
|
+
((eqv? cterm char-return) ; treat a CR and CRLF as a LF
|
1198
|
+
(if (eqv? (peek-char port) #\newline) (read-char port))
|
1199
|
+
(read-attrib-value delimiter port entities
|
1200
|
+
(cons " " new-fragments)))
|
1201
|
+
((memv cterm ssax:S-chars)
|
1202
|
+
(read-attrib-value delimiter port entities
|
1203
|
+
(cons " " new-fragments)))
|
1204
|
+
((eqv? cterm #\&)
|
1205
|
+
(cond
|
1206
|
+
((eqv? (peek-char port) #\#)
|
1207
|
+
(read-char port)
|
1208
|
+
(read-attrib-value delimiter port entities
|
1209
|
+
(cons (ssax:read-char-ref port) new-fragments)))
|
1210
|
+
(else
|
1211
|
+
(read-attrib-value delimiter port entities
|
1212
|
+
(read-named-entity port entities new-fragments)))))
|
1213
|
+
(else (parser-error port "[CleanAttrVals] broken")))))
|
1214
|
+
|
1215
|
+
; we have read "&" that introduces a named entity reference.
|
1216
|
+
; read this reference and return the result of
|
1217
|
+
; normalizing of the corresponding string
|
1218
|
+
; (that is, read-attrib-value is applied to the replacement
|
1219
|
+
; text of the entity)
|
1220
|
+
; The current position will be after ";" that terminates
|
1221
|
+
; the entity reference
|
1222
|
+
(define (read-named-entity port entities fragments)
|
1223
|
+
(let ((name (ssax:read-NCName port)))
|
1224
|
+
(assert-curr-char '(#\;) "XML [68]" port)
|
1225
|
+
(ssax:handle-parsed-entity port name entities
|
1226
|
+
(lambda (port entities fragments)
|
1227
|
+
(read-attrib-value '*eof* port entities fragments))
|
1228
|
+
(lambda (str1 str2 fragments)
|
1229
|
+
(if (equal? "" str2) (cons str1 fragments)
|
1230
|
+
(cons* str2 str1 fragments)))
|
1231
|
+
fragments)))
|
1232
|
+
|
1233
|
+
(lambda (port entities)
|
1234
|
+
(let loop ((attr-list (make-empty-attlist)))
|
1235
|
+
(if (not (ssax:ncname-starting-char? (ssax:skip-S port))) attr-list
|
1236
|
+
(let ((name (ssax:read-QName port)))
|
1237
|
+
(ssax:skip-S port)
|
1238
|
+
(assert-curr-char '(#\=) "XML [25]" port)
|
1239
|
+
(ssax:skip-S port)
|
1240
|
+
(let ((delimiter
|
1241
|
+
(assert-curr-char '(#\' #\" ) "XML [10]" port)))
|
1242
|
+
(loop
|
1243
|
+
(or (attlist-add attr-list
|
1244
|
+
(cons name
|
1245
|
+
(string-concatenate-reverse/shared
|
1246
|
+
(read-attrib-value delimiter port entities
|
1247
|
+
'()))))
|
1248
|
+
(parser-error port "[uniqattspec] broken for " name))))))))
|
1249
|
+
))
|
1250
|
+
|
1251
|
+
; a few lines of validation code
|
1252
|
+
(run-test (letrec
|
1253
|
+
((test (lambda (str decl-entities expected-res)
|
1254
|
+
(newline) (display "input: ") (write str)
|
1255
|
+
(newline) (display "Result: ")
|
1256
|
+
(let ((result
|
1257
|
+
(call-with-input-string (unesc-string str)
|
1258
|
+
(lambda (port)
|
1259
|
+
(ssax:read-attributes port decl-entities)))))
|
1260
|
+
(write result) (newline)
|
1261
|
+
(assert (equal? result expected-res))))))
|
1262
|
+
(test "" '() '())
|
1263
|
+
(test "href='http://a%tb%r%n%r%n%nc'" '()
|
1264
|
+
`((,(string->symbol "href") . "http://a b c")))
|
1265
|
+
(test "href='http://a%tb%r%r%n%rc'" '()
|
1266
|
+
`((,(string->symbol "href") . "http://a b c")))
|
1267
|
+
(test "_1 ='12&' _2= \"%r%n%t12 3\">" '()
|
1268
|
+
`((_1 . "12&") (_2 . ,(unesc-string " 12%n3"))))
|
1269
|
+
(test "%tAbc='<&>
'%nNext='12&ent;34' />"
|
1270
|
+
'((ent . "<xx>"))
|
1271
|
+
`((,(string->symbol "Abc") . ,(unesc-string "<&>%n"))
|
1272
|
+
(,(string->symbol "Next") . "12<xx>34")))
|
1273
|
+
(test "%tAbc='<&>
'%nNext='12&ent;34' />"
|
1274
|
+
'((ent . "<xx>"))
|
1275
|
+
`((,(string->symbol "Abc") . ,(unesc-string "<&>%r"))
|
1276
|
+
(,(string->symbol "Next") . "12<xx>34")))
|
1277
|
+
(test "%tAbc='<&>
'%nNext='12&en;34' />"
|
1278
|
+
`((en . ,(lambda () (open-input-string ""xx'"))))
|
1279
|
+
`((,(string->symbol "Abc") . ,(unesc-string "<&>%n"))
|
1280
|
+
(,(string->symbol "Next") . "12\"xx'34")))
|
1281
|
+
(test "%tAbc='<&>
'%nNext='12&ent;34' />"
|
1282
|
+
'((ent . "<&ent1;T;>") (ent1 . "&"))
|
1283
|
+
`((,(string->symbol "Abc") . ,(unesc-string "<&>%n"))
|
1284
|
+
(,(string->symbol "Next") . "12<&T;>34")))
|
1285
|
+
(test "%tAbc='<&>
'%nNext='12&ent;34' />"
|
1286
|
+
`((*DEFAULT* . ,(lambda (port name)
|
1287
|
+
(case name
|
1288
|
+
((ent) "<&ent1;T;>")
|
1289
|
+
((ent1) "&")
|
1290
|
+
(else (error "unrecognized" name))))))
|
1291
|
+
`((,(string->symbol "Abc") . ,(unesc-string "<&>%n"))
|
1292
|
+
(,(string->symbol "Next") . "12<&T;>34")))
|
1293
|
+
(assert (failed?
|
1294
|
+
(test "%tAbc='<&>
'%nNext='12&ent;34' />"
|
1295
|
+
'((ent . "<&ent1;T;>") (ent1 . "&")) '())))
|
1296
|
+
(assert (failed?
|
1297
|
+
(test "%tAbc='<&>
'%nNext='12&ent;34' />"
|
1298
|
+
'((ent . "<&ent;T;>") (ent1 . "&")) '())))
|
1299
|
+
(assert (failed?
|
1300
|
+
(test "%tAbc='<&>
'%nNext='12&ent;34' />"
|
1301
|
+
'((ent . "<&ent1;T;>") (ent1 . "&ent;")) '())))
|
1302
|
+
(test "html:href='http://a%tb%r%n%r%n%nc'" '()
|
1303
|
+
`(((,(string->symbol "html") . ,(string->symbol "href"))
|
1304
|
+
. "http://a b c")))
|
1305
|
+
(test "html:href='ref1' html:src='ref2'" '()
|
1306
|
+
`(((,(string->symbol "html") . ,(string->symbol "href"))
|
1307
|
+
. "ref1")
|
1308
|
+
((,(string->symbol "html") . ,(string->symbol "src"))
|
1309
|
+
. "ref2")))
|
1310
|
+
(test "html:href='ref1' xml:html='ref2'" '()
|
1311
|
+
`(((,(string->symbol "html") . ,(string->symbol "href"))
|
1312
|
+
. "ref1")
|
1313
|
+
((,ssax:Prefix-XML . ,(string->symbol "html"))
|
1314
|
+
. "ref2")))
|
1315
|
+
(assert (failed? (test "html:href='ref1' html:href='ref2'" '() '())))
|
1316
|
+
(assert (failed? (test "html:href='<' html:href='ref2'" '() '())))
|
1317
|
+
(assert (failed? (test "html:href='ref1' html:href='&ref2;'" '() '())))
|
1318
|
+
))
|
1319
|
+
|
1320
|
+
; ssax:resolve-name PORT UNRES-NAME NAMESPACES apply-default-ns?
|
1321
|
+
;
|
1322
|
+
; Convert an UNRES-NAME to a RES-NAME given the appropriate NAMESPACES
|
1323
|
+
; declarations.
|
1324
|
+
; the last parameter apply-default-ns? determines if the default
|
1325
|
+
; namespace applies (for instance, it does not for attribute names)
|
1326
|
+
;
|
1327
|
+
; Per REC-xml-names/#nsc-NSDeclared, "xml" prefix is considered pre-declared
|
1328
|
+
; and bound to the namespace name "http://www.w3.org/XML/1998/namespace".
|
1329
|
+
;
|
1330
|
+
; This procedure tests for the namespace constraints:
|
1331
|
+
; http://www.w3.org/TR/REC-xml-names/#nsc-NSDeclared
|
1332
|
+
|
1333
|
+
(define (ssax:resolve-name port unres-name namespaces apply-default-ns?)
|
1334
|
+
(cond
|
1335
|
+
((pair? unres-name) ; it's a QNAME
|
1336
|
+
(cons
|
1337
|
+
(cond
|
1338
|
+
((assq (car unres-name) namespaces) => cadr)
|
1339
|
+
((eq? (car unres-name) ssax:Prefix-XML) ssax:Prefix-XML)
|
1340
|
+
(else
|
1341
|
+
(parser-error port "[nsc-NSDeclared] broken; prefix " (car unres-name))))
|
1342
|
+
(cdr unres-name)))
|
1343
|
+
(apply-default-ns? ; Do apply the default namespace, if any
|
1344
|
+
(let ((default-ns (assq '*DEFAULT* namespaces)))
|
1345
|
+
(if (and default-ns (cadr default-ns))
|
1346
|
+
(cons (cadr default-ns) unres-name)
|
1347
|
+
unres-name))) ; no default namespace declared
|
1348
|
+
(else unres-name))) ; no prefix, don't apply the default-ns
|
1349
|
+
|
1350
|
+
|
1351
|
+
(run-test
|
1352
|
+
(let* ((namespaces
|
1353
|
+
'((HTML UHTML . URN-HTML)
|
1354
|
+
(HTML UHTML-1 . URN-HTML)
|
1355
|
+
(A UHTML . URN-HTML)))
|
1356
|
+
(namespaces-def
|
1357
|
+
(cons
|
1358
|
+
'(*DEFAULT* DEF . URN-DEF) namespaces))
|
1359
|
+
(namespaces-undef
|
1360
|
+
(cons
|
1361
|
+
'(*DEFAULT* #f . #f) namespaces-def))
|
1362
|
+
(port (current-input-port)))
|
1363
|
+
|
1364
|
+
(assert (equal? 'ABC
|
1365
|
+
(ssax:resolve-name port 'ABC namespaces #t)))
|
1366
|
+
(assert (equal? '(DEF . ABC)
|
1367
|
+
(ssax:resolve-name port 'ABC namespaces-def #t)))
|
1368
|
+
(assert (equal? 'ABC
|
1369
|
+
(ssax:resolve-name port 'ABC namespaces-def #f)))
|
1370
|
+
(assert (equal? 'ABC
|
1371
|
+
(ssax:resolve-name port 'ABC namespaces-undef #t)))
|
1372
|
+
(assert (equal? '(UHTML . ABC)
|
1373
|
+
(ssax:resolve-name port '(HTML . ABC) namespaces-def #t)))
|
1374
|
+
(assert (equal? '(UHTML . ABC)
|
1375
|
+
(ssax:resolve-name port '(HTML . ABC) namespaces-def #f)))
|
1376
|
+
(assert (equal? `(,ssax:Prefix-XML . space)
|
1377
|
+
(ssax:resolve-name port
|
1378
|
+
`(,(string->symbol "xml") . space) namespaces-def #f)))
|
1379
|
+
(assert (failed?
|
1380
|
+
(ssax:resolve-name port '(XXX . ABC) namespaces-def #f)))
|
1381
|
+
))
|
1382
|
+
|
1383
|
+
|
1384
|
+
; procedure+: ssax:uri-string->symbol URI-STR
|
1385
|
+
; Convert a URI-STR to an appropriate symbol
|
1386
|
+
(define (ssax:uri-string->symbol uri-str)
|
1387
|
+
(string->symbol uri-str))
|
1388
|
+
|
1389
|
+
; procedure+: ssax:complete-start-tag TAG PORT ELEMS ENTITIES NAMESPACES
|
1390
|
+
;
|
1391
|
+
; This procedure is to complete parsing of a start-tag markup. The
|
1392
|
+
; procedure must be called after the start tag token has been
|
1393
|
+
; read. TAG is an UNRES-NAME. ELEMS is an instance of xml-decl::elems;
|
1394
|
+
; it can be #f to tell the function to do _no_ validation of elements
|
1395
|
+
; and their attributes.
|
1396
|
+
;
|
1397
|
+
; This procedure returns several values:
|
1398
|
+
; ELEM-GI: a RES-NAME.
|
1399
|
+
; ATTRIBUTES: element's attributes, an ATTLIST of (RES-NAME . STRING)
|
1400
|
+
; pairs. The list does NOT include xmlns attributes.
|
1401
|
+
; NAMESPACES: the input list of namespaces amended with namespace
|
1402
|
+
; (re-)declarations contained within the start-tag under parsing
|
1403
|
+
; ELEM-CONTENT-MODEL
|
1404
|
+
|
1405
|
+
; On exit, the current position in PORT will be the first character after
|
1406
|
+
; #\> that terminates the start-tag markup.
|
1407
|
+
;
|
1408
|
+
; Faults detected:
|
1409
|
+
; VC: XML-Spec.html#enum
|
1410
|
+
; VC: XML-Spec.html#RequiredAttr
|
1411
|
+
; VC: XML-Spec.html#FixedAttr
|
1412
|
+
; VC: XML-Spec.html#ValueType
|
1413
|
+
; WFC: XML-Spec.html#uniqattspec (after namespaces prefixes are resolved)
|
1414
|
+
; VC: XML-Spec.html#elementvalid
|
1415
|
+
; WFC: REC-xml-names/#dt-NSName
|
1416
|
+
|
1417
|
+
; Note, although XML Recommendation does not explicitly say it,
|
1418
|
+
; xmlns and xmlns: attributes don't have to be declared (although they
|
1419
|
+
; can be declared, to specify their default value)
|
1420
|
+
|
1421
|
+
; Procedure: ssax:complete-start-tag tag-head port elems entities namespaces
|
1422
|
+
(define ssax:complete-start-tag
|
1423
|
+
|
1424
|
+
(let ((xmlns (string->symbol "xmlns"))
|
1425
|
+
(largest-dummy-decl-attr (list ssax:largest-unres-name #f #f #f)))
|
1426
|
+
|
1427
|
+
; Scan through the attlist and validate it, against decl-attrs
|
1428
|
+
; Return an assoc list with added fixed or implied attrs.
|
1429
|
+
; Note that both attlist and decl-attrs are ATTLISTs, and therefore,
|
1430
|
+
; sorted
|
1431
|
+
(define (validate-attrs port attlist decl-attrs)
|
1432
|
+
|
1433
|
+
; Check to see decl-attr is not of use type REQUIRED. Add
|
1434
|
+
; the association with the default value, if any declared
|
1435
|
+
(define (add-default-decl decl-attr result)
|
1436
|
+
(let*-values
|
1437
|
+
(((attr-name content-type use-type default-value)
|
1438
|
+
(apply values decl-attr)))
|
1439
|
+
(and (eq? use-type 'REQUIRED)
|
1440
|
+
(parser-error port "[RequiredAttr] broken for" attr-name))
|
1441
|
+
(if default-value
|
1442
|
+
(cons (cons attr-name default-value) result)
|
1443
|
+
result)))
|
1444
|
+
|
1445
|
+
(let loop ((attlist attlist) (decl-attrs decl-attrs) (result '()))
|
1446
|
+
(if (attlist-null? attlist)
|
1447
|
+
(attlist-fold add-default-decl result decl-attrs)
|
1448
|
+
(let*-values
|
1449
|
+
(((attr attr-others)
|
1450
|
+
(attlist-remove-top attlist))
|
1451
|
+
((decl-attr other-decls)
|
1452
|
+
(if (attlist-null? decl-attrs)
|
1453
|
+
(values largest-dummy-decl-attr decl-attrs)
|
1454
|
+
(attlist-remove-top decl-attrs)))
|
1455
|
+
)
|
1456
|
+
(case (name-compare (car attr) (car decl-attr))
|
1457
|
+
((<)
|
1458
|
+
(if (or (eq? xmlns (car attr))
|
1459
|
+
(and (pair? (car attr)) (eq? xmlns (caar attr))))
|
1460
|
+
(loop attr-others decl-attrs (cons attr result))
|
1461
|
+
(parser-error port "[ValueType] broken for " attr)))
|
1462
|
+
((>)
|
1463
|
+
(loop attlist other-decls
|
1464
|
+
(add-default-decl decl-attr result)))
|
1465
|
+
(else ; matched occurrence of an attr with its declaration
|
1466
|
+
(let*-values
|
1467
|
+
(((attr-name content-type use-type default-value)
|
1468
|
+
(apply values decl-attr)))
|
1469
|
+
; Run some tests on the content of the attribute
|
1470
|
+
(cond
|
1471
|
+
((eq? use-type 'FIXED)
|
1472
|
+
(or (equal? (cdr attr) default-value)
|
1473
|
+
(parser-error port "[FixedAttr] broken for " attr-name)))
|
1474
|
+
((eq? content-type 'CDATA) #t) ; everything goes
|
1475
|
+
((pair? content-type)
|
1476
|
+
(or (member (cdr attr) content-type)
|
1477
|
+
(parser-error port "[enum] broken for " attr-name "="
|
1478
|
+
(cdr attr))))
|
1479
|
+
(else
|
1480
|
+
(ssax:warn port "declared content type " content-type
|
1481
|
+
" not verified yet")))
|
1482
|
+
(loop attr-others other-decls (cons attr result)))))
|
1483
|
+
))))
|
1484
|
+
|
1485
|
+
|
1486
|
+
; Add a new namespace declaration to namespaces.
|
1487
|
+
; First we convert the uri-str to a uri-symbol and search namespaces for
|
1488
|
+
; an association (_ user-prefix . uri-symbol).
|
1489
|
+
; If found, we return the argument namespaces with an association
|
1490
|
+
; (prefix user-prefix . uri-symbol) prepended.
|
1491
|
+
; Otherwise, we prepend (prefix uri-symbol . uri-symbol)
|
1492
|
+
(define (add-ns port prefix uri-str namespaces)
|
1493
|
+
(and (equal? "" uri-str)
|
1494
|
+
(parser-error port "[dt-NSName] broken for " prefix))
|
1495
|
+
(let ((uri-symbol (ssax:uri-string->symbol uri-str)))
|
1496
|
+
(let loop ((nss namespaces))
|
1497
|
+
(cond
|
1498
|
+
((null? nss)
|
1499
|
+
(cons (cons* prefix uri-symbol uri-symbol) namespaces))
|
1500
|
+
((eq? uri-symbol (cddar nss))
|
1501
|
+
(cons (cons* prefix (cadar nss) uri-symbol) namespaces))
|
1502
|
+
(else (loop (cdr nss)))))))
|
1503
|
+
|
1504
|
+
; partition attrs into proper attrs and new namespace declarations
|
1505
|
+
; return two values: proper attrs and the updated namespace declarations
|
1506
|
+
(define (adjust-namespace-decl port attrs namespaces)
|
1507
|
+
(let loop ((attrs attrs) (proper-attrs '()) (namespaces namespaces))
|
1508
|
+
(cond
|
1509
|
+
((null? attrs) (values proper-attrs namespaces))
|
1510
|
+
((eq? xmlns (caar attrs)) ; re-decl of the default namespace
|
1511
|
+
(loop (cdr attrs) proper-attrs
|
1512
|
+
(if (equal? "" (cdar attrs)) ; un-decl of the default ns
|
1513
|
+
(cons (cons* '*DEFAULT* #f #f) namespaces)
|
1514
|
+
(add-ns port '*DEFAULT* (cdar attrs) namespaces))))
|
1515
|
+
((and (pair? (caar attrs)) (eq? xmlns (caaar attrs)))
|
1516
|
+
(loop (cdr attrs) proper-attrs
|
1517
|
+
(add-ns port (cdaar attrs) (cdar attrs) namespaces)))
|
1518
|
+
(else
|
1519
|
+
(loop (cdr attrs) (cons (car attrs) proper-attrs) namespaces)))))
|
1520
|
+
|
1521
|
+
; The body of the function
|
1522
|
+
(lambda (tag-head port elems entities namespaces)
|
1523
|
+
(let*-values
|
1524
|
+
(((attlist) (ssax:read-attributes port entities))
|
1525
|
+
((empty-el-tag?)
|
1526
|
+
(begin
|
1527
|
+
(ssax:skip-S port)
|
1528
|
+
(and
|
1529
|
+
(eqv? #\/
|
1530
|
+
(assert-curr-char '(#\> #\/) "XML [40], XML [44], no '>'" port))
|
1531
|
+
(assert-curr-char '(#\>) "XML [44], no '>'" port))))
|
1532
|
+
((elem-content decl-attrs) ; see xml-decl for their type
|
1533
|
+
(if elems ; elements declared: validate!
|
1534
|
+
(cond
|
1535
|
+
((assoc tag-head elems) =>
|
1536
|
+
(lambda (decl-elem) ; of type xml-decl::decl-elem
|
1537
|
+
(values
|
1538
|
+
(if empty-el-tag? 'EMPTY-TAG (cadr decl-elem))
|
1539
|
+
(caddr decl-elem))))
|
1540
|
+
(else
|
1541
|
+
(parser-error port "[elementvalid] broken, no decl for " tag-head)))
|
1542
|
+
(values ; non-validating parsing
|
1543
|
+
(if empty-el-tag? 'EMPTY-TAG 'ANY)
|
1544
|
+
#f) ; no attributes declared
|
1545
|
+
))
|
1546
|
+
((merged-attrs) (if decl-attrs (validate-attrs port attlist decl-attrs)
|
1547
|
+
(attlist->alist attlist)))
|
1548
|
+
((proper-attrs namespaces)
|
1549
|
+
(adjust-namespace-decl port merged-attrs namespaces))
|
1550
|
+
)
|
1551
|
+
;(cerr "proper attrs: " proper-attrs nl)
|
1552
|
+
; build the return value
|
1553
|
+
(values
|
1554
|
+
(ssax:resolve-name port tag-head namespaces #t)
|
1555
|
+
(fold-right
|
1556
|
+
(lambda (name-value attlist)
|
1557
|
+
(or
|
1558
|
+
(attlist-add attlist
|
1559
|
+
(cons (ssax:resolve-name port (car name-value) namespaces #f)
|
1560
|
+
(cdr name-value)))
|
1561
|
+
(parser-error port "[uniqattspec] after NS expansion broken for "
|
1562
|
+
name-value)))
|
1563
|
+
(make-empty-attlist)
|
1564
|
+
proper-attrs)
|
1565
|
+
namespaces
|
1566
|
+
elem-content)))))
|
1567
|
+
|
1568
|
+
(run-test
|
1569
|
+
(let* ((urn-a (string->symbol "urn:a"))
|
1570
|
+
(urn-b (string->symbol "urn:b"))
|
1571
|
+
(urn-html (string->symbol "http://w3c.org/html"))
|
1572
|
+
(namespaces
|
1573
|
+
`((#f '"UHTML" . ,urn-html)
|
1574
|
+
('"A" '"UA" . ,urn-a)))
|
1575
|
+
(test
|
1576
|
+
(lambda (tag-head-name elems str)
|
1577
|
+
(call-with-input-string str
|
1578
|
+
(lambda (port)
|
1579
|
+
(call-with-values
|
1580
|
+
(lambda ()
|
1581
|
+
(ssax:complete-start-tag
|
1582
|
+
(call-with-input-string tag-head-name
|
1583
|
+
(lambda (port) (ssax:read-QName port)))
|
1584
|
+
port
|
1585
|
+
elems '() namespaces))
|
1586
|
+
list))))))
|
1587
|
+
|
1588
|
+
; First test with no validation of elements
|
1589
|
+
;(test "TAG1" #f "")
|
1590
|
+
(assert (equal? `('"TAG1" () ,namespaces ANY)
|
1591
|
+
(test "TAG1" #f ">")))
|
1592
|
+
(assert (equal? `('"TAG1" () ,namespaces EMPTY-TAG)
|
1593
|
+
(test "TAG1" #f "/>")))
|
1594
|
+
(assert (equal? `('"TAG1" (('"HREF" . "a")) ,namespaces EMPTY-TAG)
|
1595
|
+
(test "TAG1" #f "HREF='a'/>")))
|
1596
|
+
(assert (equal? `(('"UA" . '"TAG1") (('"HREF" . "a"))
|
1597
|
+
,(cons `(*DEFAULT* '"UA" . ,urn-a) namespaces) ANY)
|
1598
|
+
(test "TAG1" #f "HREF='a' xmlns='urn:a'>")))
|
1599
|
+
(assert (equal? `('"TAG1" (('"HREF" . "a"))
|
1600
|
+
,(cons '(*DEFAULT* #f . #f) namespaces) ANY)
|
1601
|
+
(test "TAG1" #f "HREF='a' xmlns=''>")))
|
1602
|
+
(assert (failed? (test "UA:TAG1" #f "HREF='a' xmlns=''/>")))
|
1603
|
+
(assert (equal? `(('"UA" . '"TAG1") ((('"UA" . '"HREF") . "a"))
|
1604
|
+
,(cons '(*DEFAULT* #f . #f) namespaces) ANY)
|
1605
|
+
(test "A:TAG1" #f "A:HREF='a' xmlns=''>")))
|
1606
|
+
(assert (equal? `(('"UA" . '"TAG1") ((('"UA" . '"HREF") . "a"))
|
1607
|
+
,(cons `(*DEFAULT* ,urn-b . ,urn-b) namespaces) ANY)
|
1608
|
+
(test "A:TAG1" #f "A:HREF='a' xmlns='urn:b'>")))
|
1609
|
+
(assert (failed? (test "B:TAG1" #f "A:HREF='a' xmlns:b=''/>")))
|
1610
|
+
(assert (equal? `((,urn-b . '"TAG1") ((('"UA" . '"HREF") . "a"))
|
1611
|
+
,(cons `('"B" ,urn-b . ,urn-b) namespaces) ANY)
|
1612
|
+
(test "B:TAG1" #f "A:HREF='a' xmlns:B='urn:b'>")))
|
1613
|
+
(assert (equal? `((,urn-b . '"TAG1") ((('"UA" . '"HREF") . "a")
|
1614
|
+
((,urn-b . '"SRC") . "b"))
|
1615
|
+
,(cons `('"B" ,urn-b . ,urn-b) namespaces) ANY)
|
1616
|
+
(test "B:TAG1" #f
|
1617
|
+
"B:SRC='b' A:HREF='a' xmlns:B='urn:b'>")))
|
1618
|
+
(assert (equal? `((,urn-b . '"TAG1") ((('"UA" . '"HREF") . "a")
|
1619
|
+
((,urn-b . '"HREF") . "b"))
|
1620
|
+
,(cons `('"B" ,urn-b . ,urn-b) namespaces) ANY)
|
1621
|
+
(test "B:TAG1" #f
|
1622
|
+
"B:HREF=\"b\" A:HREF='a' xmlns:B='urn:b'>")))
|
1623
|
+
; must be an error! Duplicate attr
|
1624
|
+
(assert (failed? (test "B:TAG1" #f
|
1625
|
+
"HREF=\"b\" HREF='a' xmlns:B='urn:a'/>")))
|
1626
|
+
; must be an error! Duplicate attr after ns expansion
|
1627
|
+
(assert (failed? (test "B:TAG1" #f
|
1628
|
+
"B:HREF=\"b\" A:HREF='a' xmlns:B='urn:a'/>")))
|
1629
|
+
(assert (equal? `(('"UA" . '"TAG1") (('"HREF" . "a")
|
1630
|
+
(('"UA" . '"HREF") . "b"))
|
1631
|
+
,(cons `(*DEFAULT* '"UA" . ,urn-a) namespaces) ANY)
|
1632
|
+
(test "TAG1" #f
|
1633
|
+
"A:HREF=\"b\" HREF='a' xmlns='urn:a'>")))
|
1634
|
+
(assert (equal? `('"TAG1" ((('"UHTML" . '"HREF") . "a")
|
1635
|
+
((,urn-b . '"HREF") . "b"))
|
1636
|
+
,(append `(
|
1637
|
+
('"HTML" '"UHTML" . ,urn-html)
|
1638
|
+
('"B" ,urn-b . ,urn-b))
|
1639
|
+
namespaces) ANY)
|
1640
|
+
(test "TAG1" #f
|
1641
|
+
"B:HREF=\"b\" xmlns:B='urn:b' xmlns:HTML='http://w3c.org/html' HTML:HREF='a' >")))
|
1642
|
+
|
1643
|
+
; Now test the validating parsing
|
1644
|
+
; No decl for tag1
|
1645
|
+
(assert (failed? (test "TAG1" '((TAG2 ANY ()))
|
1646
|
+
"B:HREF='b' xmlns:B='urn:b'>")))
|
1647
|
+
; No decl for HREF elem
|
1648
|
+
;; (cond-expand
|
1649
|
+
;; ((not (or scm mit-scheme)) ; Regretfully, SCM treats '() as #f
|
1650
|
+
;; (assert (failed?
|
1651
|
+
;; (test "TAG1" '(('"TAG1" ANY ()))
|
1652
|
+
;; "B:HREF='b' xmlns:B='urn:b'>"))))
|
1653
|
+
;; (else #t))
|
1654
|
+
; No decl for HREF elem
|
1655
|
+
(assert (failed?
|
1656
|
+
(test "TAG1" '(('"TAG1" ANY (('"HREF1" CDATA IMPLIED #f))))
|
1657
|
+
"B:HREF='b' xmlns:B='urn:b'>")))
|
1658
|
+
(assert (equal? `('"TAG1" (('"HREF" . "b")) ,namespaces EMPTY-TAG)
|
1659
|
+
(test "TAG1" '(('"TAG1" PCDATA (('"HREF" CDATA REQUIRED #f))))
|
1660
|
+
"HREF='b'/>")))
|
1661
|
+
(assert (equal? `('"TAG1" (('"HREF" . "b")) ,namespaces PCDATA)
|
1662
|
+
(test "TAG1" '(('"TAG1" PCDATA (('"HREF" CDATA REQUIRED #f))))
|
1663
|
+
"HREF='b'>")))
|
1664
|
+
; Req'd attribute not given error
|
1665
|
+
(assert (failed?
|
1666
|
+
(test "TAG1" '(('"TAG1" PCDATA (('"HREF" CDATA REQUIRED #f))))
|
1667
|
+
">")))
|
1668
|
+
; Wrong content-type of the attribute
|
1669
|
+
(assert (failed?
|
1670
|
+
(test "TAG1" '(('"TAG1" PCDATA (('"HREF" ("c") REQUIRED #f))))
|
1671
|
+
"HREF='b'>")))
|
1672
|
+
(assert (equal? `('"TAG1" (('"HREF" . "b")) ,namespaces PCDATA)
|
1673
|
+
(test "TAG1" '(('"TAG1" PCDATA (('"HREF" ("c" "b") IMPLIED #f))))
|
1674
|
+
"HREF='b'>")))
|
1675
|
+
(assert (equal? `('"TAG1" (('"HREF" . "b")) ,namespaces PCDATA)
|
1676
|
+
(test "TAG1" '(('"TAG1" PCDATA (('"HREF" CDATA IMPLIED "c"))))
|
1677
|
+
"HREF='b'>")))
|
1678
|
+
; Bad fixed attribute
|
1679
|
+
(assert (failed?
|
1680
|
+
(test "TAG1" '(('"TAG1" PCDATA (('"HREF" CDATA FIXED "c"))))
|
1681
|
+
"HREF='b'>")))
|
1682
|
+
(assert (equal? `('"TAG1" (('"HREF" . "b")) ,namespaces PCDATA)
|
1683
|
+
(test "TAG1" '(('"TAG1" PCDATA (('"HREF" CDATA FIXED "b"))))
|
1684
|
+
"HREF='b'>")))
|
1685
|
+
(assert (equal? `('"TAG1" (('"HREF" . "b")) ,namespaces PCDATA)
|
1686
|
+
(test "TAG1" '(('"TAG1" PCDATA (('"HREF" CDATA FIXED "b")))) ">")))
|
1687
|
+
(assert (equal? `('"TAG1" (('"HREF" . "b")) ,namespaces PCDATA)
|
1688
|
+
(test "TAG1" '(('"TAG1" PCDATA (('"HREF" CDATA IMPLIED "b")))) ">")))
|
1689
|
+
(assert (equal? `('"TAG1" () ,namespaces PCDATA)
|
1690
|
+
(test "TAG1" '(('"TAG1" PCDATA (('"HREF" CDATA IMPLIED #f)))) ">")))
|
1691
|
+
; Undeclared attr
|
1692
|
+
(assert (failed?
|
1693
|
+
(test "TAG1"
|
1694
|
+
'(('"TAG1" PCDATA ((('"A" . '"HREF") CDATA IMPLIED "c"))))
|
1695
|
+
"HREF='b'>")))
|
1696
|
+
(assert (equal? `('"TAG1" (('"HREF" . "b") (('"UA" . '"HREF") . "c"))
|
1697
|
+
,namespaces PCDATA)
|
1698
|
+
(test "TAG1" '(('"TAG1" PCDATA (('"HREF" CDATA REQUIRED #f)
|
1699
|
+
(('"A" . '"HREF") CDATA IMPLIED "c"))))
|
1700
|
+
"HREF='b'>")))
|
1701
|
+
(assert (equal? `(('"UA" . '"TAG1")
|
1702
|
+
(('"HREF" . "b") (('"UA" . '"HREF") . "c"))
|
1703
|
+
,namespaces PCDATA)
|
1704
|
+
(test "A:TAG1" '((('"A" . '"TAG1") PCDATA
|
1705
|
+
(('"HREF" NMTOKEN REQUIRED #f)
|
1706
|
+
(('"A" . '"HREF") CDATA IMPLIED "c"))))
|
1707
|
+
"HREF='b'>")))
|
1708
|
+
(assert (equal? `((,urn-b . '"TAG1") (('"HREF" . "b"))
|
1709
|
+
,(cons `('"B" ,urn-b . ,urn-b) namespaces) PCDATA)
|
1710
|
+
(test "B:TAG1" '((('"B" . '"TAG1") PCDATA (('"HREF" CDATA REQUIRED #f)
|
1711
|
+
(('"xmlns" . '"B") CDATA IMPLIED "urn:b"))))
|
1712
|
+
"HREF='b'>")))
|
1713
|
+
(assert (equal? `((,urn-b . '"TAG1") (((,urn-b . '"HREF") . "b"))
|
1714
|
+
,(cons `('"B" ,urn-b . ,urn-b) namespaces) PCDATA)
|
1715
|
+
(test "B:TAG1" '((('"B" . '"TAG1") PCDATA
|
1716
|
+
((('"B" . '"HREF") CDATA REQUIRED #f)
|
1717
|
+
(('"xmlns" . '"B") CDATA IMPLIED "urn:b"))))
|
1718
|
+
"B:HREF='b'>")))
|
1719
|
+
(assert (equal? `((,urn-b . '"TAG1") (('"HREF" . "b"))
|
1720
|
+
,(cons `(*DEFAULT* ,urn-b . ,urn-b) namespaces) PCDATA)
|
1721
|
+
(test "TAG1" '(('"TAG1" PCDATA (('"HREF" CDATA REQUIRED #f)
|
1722
|
+
('"xmlns" CDATA IMPLIED "urn:b"))))
|
1723
|
+
"HREF='b'>")))
|
1724
|
+
; xmlns not declared
|
1725
|
+
(assert (equal? `((,urn-b . '"TAG1") (('"HREF" . "b"))
|
1726
|
+
,(cons `(*DEFAULT* ,urn-b . ,urn-b) namespaces) PCDATA)
|
1727
|
+
(test "TAG1" '(('"TAG1" PCDATA (('"HREF" CDATA REQUIRED #f)
|
1728
|
+
)))
|
1729
|
+
"HREF='b' xmlns='urn:b'>")))
|
1730
|
+
; xmlns:B not declared
|
1731
|
+
(assert (equal? `((,urn-b . '"TAG1") (((,urn-b . '"HREF") . "b"))
|
1732
|
+
,(cons `('"B" ,urn-b . ,urn-b) namespaces) PCDATA)
|
1733
|
+
(test "B:TAG1" '((('"B" . '"TAG1") PCDATA
|
1734
|
+
((('"B" . '"HREF") CDATA REQUIRED #f)
|
1735
|
+
)))
|
1736
|
+
"B:HREF='b' xmlns:B='urn:b'>")))
|
1737
|
+
))
|
1738
|
+
|
1739
|
+
; procedure+: ssax:read-external-id PORT
|
1740
|
+
;
|
1741
|
+
; This procedure parses an ExternalID production:
|
1742
|
+
; [75] ExternalID ::= 'SYSTEM' S SystemLiteral
|
1743
|
+
; | 'PUBLIC' S PubidLiteral S SystemLiteral
|
1744
|
+
; [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
|
1745
|
+
; [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
|
1746
|
+
; [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9]
|
1747
|
+
; | [-'()+,./:=?;!*#@$_%]
|
1748
|
+
;
|
1749
|
+
; This procedure is supposed to be called when an ExternalID is expected;
|
1750
|
+
; that is, the current character must be either #\S or #\P that start
|
1751
|
+
; correspondingly a SYSTEM or PUBLIC token. This procedure returns the
|
1752
|
+
; SystemLiteral as a string. A PubidLiteral is disregarded if present.
|
1753
|
+
|
1754
|
+
(define (ssax:read-external-id port)
|
1755
|
+
(let ((discriminator (ssax:read-NCName port)))
|
1756
|
+
(assert-curr-char ssax:S-chars "space after SYSTEM or PUBLIC" port)
|
1757
|
+
(ssax:skip-S port)
|
1758
|
+
(let ((delimiter
|
1759
|
+
(assert-curr-char '(#\' #\" ) "XML [11], XML [12]" port)))
|
1760
|
+
(cond
|
1761
|
+
((eq? discriminator (string->symbol "SYSTEM"))
|
1762
|
+
(begin0
|
1763
|
+
(next-token '() (list delimiter) "XML [11]" port)
|
1764
|
+
(read-char port) ; reading the closing delim
|
1765
|
+
))
|
1766
|
+
((eq? discriminator (string->symbol "PUBLIC"))
|
1767
|
+
(skip-until (list delimiter) port)
|
1768
|
+
(assert-curr-char ssax:S-chars "space after PubidLiteral" port)
|
1769
|
+
(ssax:skip-S port)
|
1770
|
+
(let* ((delimiter
|
1771
|
+
(assert-curr-char '(#\' #\" ) "XML [11]" port))
|
1772
|
+
(systemid
|
1773
|
+
(next-token '() (list delimiter) "XML [11]" port)))
|
1774
|
+
(read-char port) ; reading the closing delim
|
1775
|
+
systemid))
|
1776
|
+
(else
|
1777
|
+
(parser-error port "XML [75], " discriminator
|
1778
|
+
" rather than SYSTEM or PUBLIC"))))))
|
1779
|
+
|
1780
|
+
|
1781
|
+
;-----------------------------------------------------------------------------
|
1782
|
+
; Higher-level parsers and scanners
|
1783
|
+
;
|
1784
|
+
; They parse productions corresponding to the whole (document) entity
|
1785
|
+
; or its higher-level pieces (prolog, root element, etc).
|
1786
|
+
|
1787
|
+
|
1788
|
+
; Scan the Misc production in the context
|
1789
|
+
; [1] document ::= prolog element Misc*
|
1790
|
+
; [22] prolog ::= XMLDecl? Misc* (doctypedec l Misc*)?
|
1791
|
+
; [27] Misc ::= Comment | PI | S
|
1792
|
+
;
|
1793
|
+
; The following function should be called in the prolog or epilog contexts.
|
1794
|
+
; In these contexts, whitespaces are completely ignored.
|
1795
|
+
; The return value from ssax:scan-Misc is either a PI-token,
|
1796
|
+
; a DECL-token, a START token, or EOF.
|
1797
|
+
; Comments are ignored and not reported.
|
1798
|
+
|
1799
|
+
(define (ssax:scan-Misc port)
|
1800
|
+
(let loop ((c (ssax:skip-S port)))
|
1801
|
+
(cond
|
1802
|
+
((eof-object? c) c)
|
1803
|
+
((not (char=? c #\<))
|
1804
|
+
(parser-error port "XML [22], char '" c "' unexpected"))
|
1805
|
+
(else
|
1806
|
+
(let ((token (ssax:read-markup-token port)))
|
1807
|
+
(case (xml-token-kind token)
|
1808
|
+
((COMMENT) (loop (ssax:skip-S port)))
|
1809
|
+
((PI DECL START) token)
|
1810
|
+
(else
|
1811
|
+
(parser-error port "XML [22], unexpected token of kind "
|
1812
|
+
(xml-token-kind token)
|
1813
|
+
))))))))
|
1814
|
+
|
1815
|
+
; procedure+: ssax:read-char-data PORT EXPECT-EOF? STR-HANDLER SEED
|
1816
|
+
;
|
1817
|
+
; This procedure is to read the character content of an XML document
|
1818
|
+
; or an XML element.
|
1819
|
+
; [43] content ::=
|
1820
|
+
; (element | CharData | Reference | CDSect | PI
|
1821
|
+
; | Comment)*
|
1822
|
+
; To be more precise, the procedure reads CharData, expands CDSect
|
1823
|
+
; and character entities, and skips comments. The procedure stops
|
1824
|
+
; at a named reference, EOF, at the beginning of a PI or a start/end tag.
|
1825
|
+
;
|
1826
|
+
; port
|
1827
|
+
; a PORT to read
|
1828
|
+
; expect-eof?
|
1829
|
+
; a boolean indicating if EOF is normal, i.e., the character
|
1830
|
+
; data may be terminated by the EOF. EOF is normal
|
1831
|
+
; while processing a parsed entity.
|
1832
|
+
; str-handler
|
1833
|
+
; a STR-HANDLER
|
1834
|
+
; seed
|
1835
|
+
; an argument passed to the first invocation of STR-HANDLER.
|
1836
|
+
;
|
1837
|
+
; The procedure returns two results: SEED and TOKEN.
|
1838
|
+
; The SEED is the result of the last invocation of STR-HANDLER, or the
|
1839
|
+
; original seed if STR-HANDLER was never called.
|
1840
|
+
;
|
1841
|
+
; TOKEN can be either an eof-object (this can happen only if
|
1842
|
+
; expect-eof? was #t), or:
|
1843
|
+
; - an xml-token describing a START tag or an END-tag;
|
1844
|
+
; For a start token, the caller has to finish reading it.
|
1845
|
+
; - an xml-token describing the beginning of a PI. It's up to an
|
1846
|
+
; application to read or skip through the rest of this PI;
|
1847
|
+
; - an xml-token describing a named entity reference.
|
1848
|
+
;
|
1849
|
+
; CDATA sections and character references are expanded inline and
|
1850
|
+
; never returned. Comments are silently disregarded.
|
1851
|
+
;
|
1852
|
+
; As the XML Recommendation requires, all whitespace in character data
|
1853
|
+
; must be preserved. However, a CR character (#xD) must be disregarded
|
1854
|
+
; if it appears before a LF character (#xA), or replaced by a #xA character
|
1855
|
+
; otherwise. See Secs. 2.10 and 2.11 of the XML Recommendation. See also
|
1856
|
+
; the canonical XML Recommendation.
|
1857
|
+
|
1858
|
+
; ssax:read-char-data port expect-eof? str-handler seed
|
1859
|
+
(define ssax:read-char-data
|
1860
|
+
(let
|
1861
|
+
((terminators-usual (list #\< #\& char-return))
|
1862
|
+
(terminators-usual-eof (list #\< '*eof* #\& char-return))
|
1863
|
+
|
1864
|
+
(handle-fragment
|
1865
|
+
(lambda (fragment str-handler seed)
|
1866
|
+
(if (string-null? fragment) seed
|
1867
|
+
(str-handler fragment "" seed))))
|
1868
|
+
)
|
1869
|
+
|
1870
|
+
(lambda (port expect-eof? str-handler seed)
|
1871
|
+
|
1872
|
+
; Very often, the first character we encounter is #\<
|
1873
|
+
; Therefore, we handle this case in a special, fast path
|
1874
|
+
(if (eqv? #\< (peek-char port))
|
1875
|
+
|
1876
|
+
; The fast path
|
1877
|
+
(let ((token (ssax:read-markup-token port)))
|
1878
|
+
(case (xml-token-kind token)
|
1879
|
+
((START END) ; The most common case
|
1880
|
+
(values seed token))
|
1881
|
+
((CDSECT)
|
1882
|
+
(let ((seed (ssax:read-cdata-body port str-handler seed)))
|
1883
|
+
(ssax:read-char-data port expect-eof? str-handler seed)))
|
1884
|
+
((COMMENT) (ssax:read-char-data port expect-eof?
|
1885
|
+
str-handler seed))
|
1886
|
+
(else
|
1887
|
+
(values seed token))))
|
1888
|
+
|
1889
|
+
|
1890
|
+
; The slow path
|
1891
|
+
(let ((char-data-terminators
|
1892
|
+
(if expect-eof? terminators-usual-eof terminators-usual)))
|
1893
|
+
|
1894
|
+
(let loop ((seed seed))
|
1895
|
+
(let* ((fragment
|
1896
|
+
(next-token '() char-data-terminators
|
1897
|
+
"reading char data" port))
|
1898
|
+
(term-char (peek-char port)) ; one of char-data-terminators
|
1899
|
+
)
|
1900
|
+
(if (eof-object? term-char)
|
1901
|
+
(values
|
1902
|
+
(handle-fragment fragment str-handler seed)
|
1903
|
+
term-char)
|
1904
|
+
(case term-char
|
1905
|
+
((#\<)
|
1906
|
+
(let ((token (ssax:read-markup-token port)))
|
1907
|
+
(case (xml-token-kind token)
|
1908
|
+
((CDSECT)
|
1909
|
+
(loop
|
1910
|
+
(ssax:read-cdata-body port str-handler
|
1911
|
+
(handle-fragment fragment str-handler seed))))
|
1912
|
+
((COMMENT)
|
1913
|
+
(loop (handle-fragment fragment str-handler seed)))
|
1914
|
+
(else
|
1915
|
+
(values
|
1916
|
+
(handle-fragment fragment str-handler seed)
|
1917
|
+
token)))))
|
1918
|
+
((#\&)
|
1919
|
+
(case (peek-next-char port)
|
1920
|
+
((#\#) (read-char port)
|
1921
|
+
(loop (str-handler fragment
|
1922
|
+
(ssax:read-char-ref port)
|
1923
|
+
seed)))
|
1924
|
+
(else
|
1925
|
+
(let ((name (ssax:read-NCName port)))
|
1926
|
+
(assert-curr-char '(#\;) "XML [68]" port)
|
1927
|
+
(values
|
1928
|
+
(handle-fragment fragment str-handler seed)
|
1929
|
+
(make-xml-token 'ENTITY-REF name))))))
|
1930
|
+
(else ; This must be a CR character
|
1931
|
+
(if (eqv? (peek-next-char port) #\newline)
|
1932
|
+
(read-char port))
|
1933
|
+
(loop (str-handler fragment (string #\newline) seed))))
|
1934
|
+
))))))))
|
1935
|
+
|
1936
|
+
|
1937
|
+
; a few lines of validation code
|
1938
|
+
(run-test (letrec
|
1939
|
+
((a-tag (make-xml-token 'START (string->symbol "BR")))
|
1940
|
+
(a-ref (make-xml-token 'ENTITY-REF (string->symbol "lt")))
|
1941
|
+
(eof-object (lambda () eof-object)) ; a unique value
|
1942
|
+
(str-handler (lambda (fragment foll-fragment seed)
|
1943
|
+
(if (string-null? foll-fragment) (cons fragment seed)
|
1944
|
+
(cons* foll-fragment fragment seed))))
|
1945
|
+
(test (lambda (str expect-eof? expected-data expected-token)
|
1946
|
+
(newline) (display "body: ") (write str)
|
1947
|
+
(newline) (display "Result: ")
|
1948
|
+
(let*-values
|
1949
|
+
(((seed token)
|
1950
|
+
(call-with-input-string (unesc-string str)
|
1951
|
+
(lambda (port)
|
1952
|
+
(ssax:read-char-data port expect-eof? str-handler '()))))
|
1953
|
+
((result) (reverse seed)))
|
1954
|
+
(write result)
|
1955
|
+
(display " ")
|
1956
|
+
(display token)
|
1957
|
+
(assert (equal? result (map unesc-string expected-data))
|
1958
|
+
(if (eq? expected-token eof-object)
|
1959
|
+
(eof-object? token)
|
1960
|
+
(equal? token expected-token))))))
|
1961
|
+
)
|
1962
|
+
(test "" #t '() eof-object)
|
1963
|
+
(assert (failed? (test "" #f '() eof-object)))
|
1964
|
+
(test " " #t '(" ") eof-object)
|
1965
|
+
(test "<BR/>" #f '() a-tag)
|
1966
|
+
(test " <BR />" #f '(" ") a-tag)
|
1967
|
+
|
1968
|
+
(test " <" #f '(" ") a-ref)
|
1969
|
+
(test " a<" #f '(" a") a-ref)
|
1970
|
+
(test " a <" #f '(" a ") a-ref)
|
1971
|
+
|
1972
|
+
(test " <!-- comment--> a a<BR/>" #f '(" " " a a") a-tag)
|
1973
|
+
(test " <!-- comment-->%ra a<BR/>" #f '(" " "" "%n" "a a") a-tag)
|
1974
|
+
(test " <!-- comment-->%r%na a<BR/>" #f '(" " "" "%n" "a a") a-tag)
|
1975
|
+
(test " <!-- comment-->%r%na%t%r%r%na<BR/>" #f
|
1976
|
+
'(" " "" "%n" "a%t" "%n" "" "%n" "a") a-tag)
|
1977
|
+
(test "a<!-- comment--> a a<BR/>" #f '("a" " a a") a-tag)
|
1978
|
+
(test "!<BR/>" #f '("" "!") a-tag)
|
1979
|
+
(test "!%n<BR/>" #f '("" "!" "%n") a-tag)
|
1980
|
+
(test "%t!%n<BR/>" #f '("%t" "!" "%n") a-tag)
|
1981
|
+
(test "%t!%na a<BR/>" #f '("%t" "!" "%na a") a-tag)
|
1982
|
+
(test "%t!%ra a<BR/>" #f '("%t" "!" "" "%n" "a a") a-tag)
|
1983
|
+
(test "%t!%r%na a<BR/>" #f '("%t" "!" "" "%n" "a a") a-tag)
|
1984
|
+
|
1985
|
+
(test " %ta ! b <BR/>" #f '(" %ta " "!" " b ") a-tag)
|
1986
|
+
(test " %ta   b <BR/>" #f '(" %ta " " " " b ") a-tag)
|
1987
|
+
|
1988
|
+
(test "<![CDATA[<]]><BR/>" #f '("<") a-tag)
|
1989
|
+
(test "<![CDATA[]]]><BR/>" #f '("]") a-tag)
|
1990
|
+
(test "%t<![CDATA[<]]><BR/>" #f '("%t" "<") a-tag)
|
1991
|
+
(test "%t<![CDATA[<]]>a b<BR/>" #f '("%t" "<" "a b") a-tag)
|
1992
|
+
(test "%t<![CDATA[<]]> a b<BR/>" #f '("%t" "<" " a b") a-tag)
|
1993
|
+
|
1994
|
+
(test "%td <![CDATA[ <%r%r%n]]> a b<BR/>" #f
|
1995
|
+
'("%td " " <" "%n" "" "%n" " a b") a-tag)
|
1996
|
+
))
|
1997
|
+
|
1998
|
+
|
1999
|
+
|
2000
|
+
; procedure+: ssax:assert-token TOKEN KIND GI
|
2001
|
+
; Make sure that TOKEN is of anticipated KIND and has anticipated GI
|
2002
|
+
; Note GI argument may actually be a pair of two symbols, Namespace
|
2003
|
+
; URI or the prefix, and of the localname.
|
2004
|
+
; If the assertion fails, error-cont is evaluated by passing it
|
2005
|
+
; three arguments: token kind gi. The result of error-cont is returned.
|
2006
|
+
(define (ssax:assert-token token kind gi error-cont)
|
2007
|
+
(or
|
2008
|
+
(and (xml-token? token)
|
2009
|
+
(eq? kind (xml-token-kind token))
|
2010
|
+
(equal? gi (xml-token-head token)))
|
2011
|
+
(error-cont token kind gi)))
|
2012
|
+
|
2013
|
+
;========================================================================
|
2014
|
+
; Highest-level parsers: XML to SXML
|
2015
|
+
|
2016
|
+
; These parsers are a set of syntactic forms to instantiate a SSAX parser.
|
2017
|
+
; A user can instantiate the parser to do the full validation, or
|
2018
|
+
; no validation, or any particular validation. The user specifies
|
2019
|
+
; which PI he wants to be notified about. The user tells what to do
|
2020
|
+
; with the parsed character and element data. The latter handlers
|
2021
|
+
; determine if the parsing follows a SAX or a DOM model.
|
2022
|
+
|
2023
|
+
; syntax: ssax:make-pi-parser my-pi-handlers
|
2024
|
+
; Create a parser to parse and process one Processing Element (PI).
|
2025
|
+
|
2026
|
+
; my-pi-handlers
|
2027
|
+
; An assoc list of pairs (PI-TAG . PI-HANDLER)
|
2028
|
+
; where PI-TAG is an NCName symbol, the PI target, and
|
2029
|
+
; PI-HANDLER is a procedure PORT PI-TAG SEED
|
2030
|
+
; where PORT points to the first symbol after the PI target.
|
2031
|
+
; The handler should read the rest of the PI up to and including
|
2032
|
+
; the combination '?>' that terminates the PI. The handler should
|
2033
|
+
; return a new seed.
|
2034
|
+
; One of the PI-TAGs may be the symbol *DEFAULT*. The corresponding
|
2035
|
+
; handler will handle PIs that no other handler will. If the
|
2036
|
+
; *DEFAULT* PI-TAG is not specified, ssax:make-pi-parser will assume
|
2037
|
+
; the default handler that skips the body of the PI
|
2038
|
+
;
|
2039
|
+
; The output of the ssax:make-pi-parser is a procedure
|
2040
|
+
; PORT PI-TAG SEED
|
2041
|
+
; that will parse the current PI according to the user-specified handlers.
|
2042
|
+
;
|
2043
|
+
; The previous version of ssax:make-pi-parser was a low-level macro:
|
2044
|
+
; (define-macro ssax:make-pi-parser
|
2045
|
+
; (lambda (my-pi-handlers)
|
2046
|
+
; `(lambda (port target seed)
|
2047
|
+
; (case target
|
2048
|
+
; ; Generate the body of the case statement
|
2049
|
+
; ,@(let loop ((pi-handlers my-pi-handlers) (default #f))
|
2050
|
+
; (cond
|
2051
|
+
; ((null? pi-handlers)
|
2052
|
+
; (if default `((else (,default port target seed)))
|
2053
|
+
; '((else
|
2054
|
+
; (ssax:warn port "Skipping PI: " target nl)
|
2055
|
+
; (ssax:skip-pi port)
|
2056
|
+
; seed))))
|
2057
|
+
; ((eq? '*DEFAULT* (caar pi-handlers))
|
2058
|
+
; (loop (cdr pi-handlers) (cdar pi-handlers)))
|
2059
|
+
; (else
|
2060
|
+
; (cons
|
2061
|
+
; `((,(caar pi-handlers)) (,(cdar pi-handlers) port target seed))
|
2062
|
+
; (loop (cdr pi-handlers) default)))))))))
|
2063
|
+
|
2064
|
+
(define-syntax ssax:make-pi-parser
|
2065
|
+
(syntax-rules ()
|
2066
|
+
((ssax:make-pi-parser orig-handlers)
|
2067
|
+
(letrec-syntax
|
2068
|
+
; Generate the clauses of the case statement
|
2069
|
+
((loop
|
2070
|
+
(syntax-rules (*DEFAULT*)
|
2071
|
+
((loop () #f accum port target seed) ; no default
|
2072
|
+
(make-case
|
2073
|
+
((else
|
2074
|
+
(ssax:warn port "Skipping PI: " target nl)
|
2075
|
+
(ssax:skip-pi port)
|
2076
|
+
seed)
|
2077
|
+
. accum)
|
2078
|
+
() target))
|
2079
|
+
((loop () default accum port target seed)
|
2080
|
+
(make-case
|
2081
|
+
((else (default port target seed)) . accum)
|
2082
|
+
() target))
|
2083
|
+
((loop ((*DEFAULT* . default) . handlers) old-def accum
|
2084
|
+
port target seed)
|
2085
|
+
(loop handlers default accum port target seed))
|
2086
|
+
((loop ((tag . handler) . handlers) default accum port target seed)
|
2087
|
+
(loop handlers default
|
2088
|
+
(((tag) (handler port target seed)) . accum)
|
2089
|
+
port target seed))
|
2090
|
+
))
|
2091
|
+
(make-case ; Reverse the clauses, make the 'case'
|
2092
|
+
(syntax-rules ()
|
2093
|
+
((make-case () clauses target)
|
2094
|
+
(case target . clauses))
|
2095
|
+
((make-case (clause . clauses) accum target)
|
2096
|
+
(make-case clauses (clause . accum) target)))
|
2097
|
+
))
|
2098
|
+
(lambda (port target seed)
|
2099
|
+
(loop orig-handlers #f () port target seed))
|
2100
|
+
))))
|
2101
|
+
|
2102
|
+
(run-test
|
2103
|
+
(pp (ssax:make-pi-parser ()))
|
2104
|
+
(pp (ssax:make-pi-parser ((xml . (lambda (port target seed) seed)))))
|
2105
|
+
(pp (ssax:make-pi-parser ((xml . (lambda (port target seed) seed))
|
2106
|
+
(html . list)
|
2107
|
+
(*DEFAULT* . ssax:warn))))
|
2108
|
+
)
|
2109
|
+
|
2110
|
+
; syntax: ssax:make-elem-parser my-new-level-seed my-finish-element
|
2111
|
+
; my-char-data-handler my-pi-handlers
|
2112
|
+
|
2113
|
+
; Create a parser to parse and process one element, including its
|
2114
|
+
; character content or children elements. The parser is typically
|
2115
|
+
; applied to the root element of a document.
|
2116
|
+
|
2117
|
+
; my-new-level-seed
|
2118
|
+
; procedure ELEM-GI ATTRIBUTES NAMESPACES EXPECTED-CONTENT SEED
|
2119
|
+
; where ELEM-GI is a RES-NAME of the element
|
2120
|
+
; about to be processed.
|
2121
|
+
; This procedure is to generate the seed to be passed
|
2122
|
+
; to handlers that process the content of the element.
|
2123
|
+
; This is the function identified as 'fdown' in the denotational
|
2124
|
+
; semantics of the XML parser given in the title comments to this
|
2125
|
+
; file.
|
2126
|
+
;
|
2127
|
+
; my-finish-element
|
2128
|
+
; procedure ELEM-GI ATTRIBUTES NAMESPACES PARENT-SEED SEED
|
2129
|
+
; This procedure is called when parsing of ELEM-GI is finished.
|
2130
|
+
; The SEED is the result from the last content parser (or
|
2131
|
+
; from my-new-level-seed if the element has the empty content).
|
2132
|
+
; PARENT-SEED is the same seed as was passed to my-new-level-seed.
|
2133
|
+
; The procedure is to generate a seed that will be the result
|
2134
|
+
; of the element parser.
|
2135
|
+
; This is the function identified as 'fup' in the denotational
|
2136
|
+
; semantics of the XML parser given in the title comments to this
|
2137
|
+
; file.
|
2138
|
+
;
|
2139
|
+
; my-char-data-handler
|
2140
|
+
; A STR-HANDLER
|
2141
|
+
;
|
2142
|
+
; my-pi-handlers
|
2143
|
+
; See ssax:make-pi-handler above
|
2144
|
+
;
|
2145
|
+
|
2146
|
+
; The generated parser is a
|
2147
|
+
; procedure START-TAG-HEAD PORT ELEMS ENTITIES
|
2148
|
+
; NAMESPACES PRESERVE-WS? SEED
|
2149
|
+
; The procedure must be called after the start tag token has been
|
2150
|
+
; read. START-TAG-HEAD is an UNRES-NAME from the start-element tag.
|
2151
|
+
; ELEMS is an instance of xml-decl::elems.
|
2152
|
+
; See ssax:complete-start-tag::preserve-ws?
|
2153
|
+
|
2154
|
+
; Faults detected:
|
2155
|
+
; VC: XML-Spec.html#elementvalid
|
2156
|
+
; WFC: XML-Spec.html#GIMatch
|
2157
|
+
|
2158
|
+
|
2159
|
+
(define-syntax ssax:make-elem-parser
|
2160
|
+
(syntax-rules ()
|
2161
|
+
((ssax:make-elem-parser my-new-level-seed my-finish-element
|
2162
|
+
my-char-data-handler my-pi-handlers)
|
2163
|
+
|
2164
|
+
(lambda (start-tag-head port elems entities namespaces
|
2165
|
+
preserve-ws? seed)
|
2166
|
+
|
2167
|
+
(define xml-space-gi (cons ssax:Prefix-XML
|
2168
|
+
(string->symbol "space")))
|
2169
|
+
|
2170
|
+
(let handle-start-tag ((start-tag-head start-tag-head)
|
2171
|
+
(port port) (entities entities)
|
2172
|
+
(namespaces namespaces)
|
2173
|
+
(preserve-ws? preserve-ws?) (parent-seed seed))
|
2174
|
+
(let*-values
|
2175
|
+
(((elem-gi attributes namespaces expected-content)
|
2176
|
+
(ssax:complete-start-tag start-tag-head port elems
|
2177
|
+
entities namespaces))
|
2178
|
+
((seed)
|
2179
|
+
(my-new-level-seed elem-gi attributes
|
2180
|
+
namespaces expected-content parent-seed)))
|
2181
|
+
(case expected-content
|
2182
|
+
((EMPTY-TAG)
|
2183
|
+
(my-finish-element
|
2184
|
+
elem-gi attributes namespaces parent-seed seed))
|
2185
|
+
((EMPTY) ; The end tag must immediately follow
|
2186
|
+
(ssax:assert-token
|
2187
|
+
(and (eqv? #\< (ssax:skip-S port)) (ssax:read-markup-token port))
|
2188
|
+
'END start-tag-head
|
2189
|
+
(lambda (token exp-kind exp-head)
|
2190
|
+
(parser-error port "[elementvalid] broken for " token
|
2191
|
+
" while expecting "
|
2192
|
+
exp-kind exp-head)))
|
2193
|
+
(my-finish-element
|
2194
|
+
elem-gi attributes namespaces parent-seed seed))
|
2195
|
+
(else ; reading the content...
|
2196
|
+
(let ((preserve-ws? ; inherit or set the preserve-ws? flag
|
2197
|
+
(cond
|
2198
|
+
((assoc xml-space-gi attributes) =>
|
2199
|
+
(lambda (name-value)
|
2200
|
+
(equal? "preserve" (cdr name-value))))
|
2201
|
+
(else preserve-ws?))))
|
2202
|
+
(let loop ((port port) (entities entities)
|
2203
|
+
(expect-eof? #f) (seed seed))
|
2204
|
+
(let*-values
|
2205
|
+
(((seed term-token)
|
2206
|
+
(ssax:read-char-data port expect-eof?
|
2207
|
+
my-char-data-handler seed)))
|
2208
|
+
(if (eof-object? term-token)
|
2209
|
+
seed
|
2210
|
+
(case (xml-token-kind term-token)
|
2211
|
+
((END)
|
2212
|
+
(ssax:assert-token term-token 'END start-tag-head
|
2213
|
+
(lambda (token exp-kind exp-head)
|
2214
|
+
(parser-error port "[GIMatch] broken for "
|
2215
|
+
term-token " while expecting "
|
2216
|
+
exp-kind exp-head)))
|
2217
|
+
(my-finish-element
|
2218
|
+
elem-gi attributes namespaces parent-seed seed))
|
2219
|
+
((PI)
|
2220
|
+
(let ((seed
|
2221
|
+
((ssax:make-pi-parser my-pi-handlers)
|
2222
|
+
port (xml-token-head term-token) seed)))
|
2223
|
+
(loop port entities expect-eof? seed)))
|
2224
|
+
((ENTITY-REF)
|
2225
|
+
(let ((seed
|
2226
|
+
(ssax:handle-parsed-entity
|
2227
|
+
port (xml-token-head term-token)
|
2228
|
+
entities
|
2229
|
+
(lambda (port entities seed)
|
2230
|
+
(loop port entities #t seed))
|
2231
|
+
my-char-data-handler
|
2232
|
+
seed))) ; keep on reading the content after ent
|
2233
|
+
(loop port entities expect-eof? seed)))
|
2234
|
+
((START) ; Start of a child element
|
2235
|
+
(if (eq? expected-content 'PCDATA)
|
2236
|
+
(parser-error port "[elementvalid] broken for "
|
2237
|
+
elem-gi
|
2238
|
+
" with char content only; unexpected token "
|
2239
|
+
term-token))
|
2240
|
+
; Do other validation of the element content
|
2241
|
+
(let ((seed
|
2242
|
+
(handle-start-tag
|
2243
|
+
(xml-token-head term-token)
|
2244
|
+
port entities namespaces
|
2245
|
+
preserve-ws? seed)))
|
2246
|
+
(loop port entities expect-eof? seed)))
|
2247
|
+
(else
|
2248
|
+
(parser-error port "XML [43] broken for "
|
2249
|
+
term-token))))))))
|
2250
|
+
)))
|
2251
|
+
))))
|
2252
|
+
|
2253
|
+
|
2254
|
+
; syntax: ssax:make-parser user-handler-tag user-handler-proc ...
|
2255
|
+
;
|
2256
|
+
; Create an XML parser, an instance of the XML parsing framework.
|
2257
|
+
; This will be a SAX, a DOM, or a specialized parser depending
|
2258
|
+
; on the supplied user-handlers.
|
2259
|
+
|
2260
|
+
; user-handler-tag is a symbol that identifies a procedural expression
|
2261
|
+
; that follows the tag. Given below are tags and signatures of the
|
2262
|
+
; corresponding procedures. Not all tags have to be specified. If some
|
2263
|
+
; are omitted, reasonable defaults will apply.
|
2264
|
+
;
|
2265
|
+
|
2266
|
+
; tag: DOCTYPE
|
2267
|
+
; handler-procedure: PORT DOCNAME SYSTEMID INTERNAL-SUBSET? SEED
|
2268
|
+
; If internal-subset? is #t, the current position in the port
|
2269
|
+
; is right after we have read #\[ that begins the internal DTD subset.
|
2270
|
+
; We must finish reading of this subset before we return
|
2271
|
+
; (or must call skip-internal-subset if we aren't interested in reading it).
|
2272
|
+
; The port at exit must be at the first symbol after the whole
|
2273
|
+
; DOCTYPE declaration.
|
2274
|
+
; The handler-procedure must generate four values:
|
2275
|
+
; ELEMS ENTITIES NAMESPACES SEED
|
2276
|
+
; See xml-decl::elems for ELEMS. It may be #f to switch off the validation.
|
2277
|
+
; NAMESPACES will typically contain USER-PREFIXes for selected URI-SYMBs.
|
2278
|
+
; The default handler-procedure skips the internal subset,
|
2279
|
+
; if any, and returns (values #f '() '() seed)
|
2280
|
+
|
2281
|
+
; tag: UNDECL-ROOT
|
2282
|
+
; handler-procedure: ELEM-GI SEED
|
2283
|
+
; where ELEM-GI is an UNRES-NAME of the root element. This procedure
|
2284
|
+
; is called when an XML document under parsing contains _no_ DOCTYPE
|
2285
|
+
; declaration.
|
2286
|
+
; The handler-procedure, as a DOCTYPE handler procedure above,
|
2287
|
+
; must generate four values:
|
2288
|
+
; ELEMS ENTITIES NAMESPACES SEED
|
2289
|
+
; The default handler-procedure returns (values #f '() '() seed)
|
2290
|
+
|
2291
|
+
; tag: DECL-ROOT
|
2292
|
+
; handler-procedure: ELEM-GI SEED
|
2293
|
+
; where ELEM-GI is an UNRES-NAME of the root element. This procedure
|
2294
|
+
; is called when an XML document under parsing does contains the DOCTYPE
|
2295
|
+
; declaration.
|
2296
|
+
; The handler-procedure must generate a new SEED (and verify
|
2297
|
+
; that the name of the root element matches the doctype, if the handler
|
2298
|
+
; so wishes).
|
2299
|
+
; The default handler-procedure is the identity function.
|
2300
|
+
|
2301
|
+
; tag: NEW-LEVEL-SEED
|
2302
|
+
; handler-procedure: see ssax:make-elem-parser, my-new-level-seed
|
2303
|
+
|
2304
|
+
; tag: FINISH-ELEMENT
|
2305
|
+
; handler-procedure: see ssax:make-elem-parser, my-finish-element
|
2306
|
+
|
2307
|
+
; tag: CHAR-DATA-HANDLER
|
2308
|
+
; handler-procedure: see ssax:make-elem-parser, my-char-data-handler
|
2309
|
+
|
2310
|
+
; tag: PI
|
2311
|
+
; handler-procedure: see ssax:make-pi-parser
|
2312
|
+
; The default value is '()
|
2313
|
+
|
2314
|
+
; The generated parser is a
|
2315
|
+
; procedure PORT SEED
|
2316
|
+
|
2317
|
+
; This procedure parses the document prolog and then exits to
|
2318
|
+
; an element parser (created by ssax:make-elem-parser) to handle
|
2319
|
+
; the rest.
|
2320
|
+
;
|
2321
|
+
; [1] document ::= prolog element Misc*
|
2322
|
+
; [22] prolog ::= XMLDecl? Misc* (doctypedec | Misc*)?
|
2323
|
+
; [27] Misc ::= Comment | PI | S
|
2324
|
+
;
|
2325
|
+
; [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
|
2326
|
+
; ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
|
2327
|
+
; [29] markupdecl ::= elementdecl | AttlistDecl
|
2328
|
+
; | EntityDecl
|
2329
|
+
; | NotationDecl | PI
|
2330
|
+
; | Comment
|
2331
|
+
;
|
2332
|
+
|
2333
|
+
|
2334
|
+
; This is ssax:make-parser with all the (specialization) handlers given
|
2335
|
+
; as positional arguments. It is called by ssax:make-parser, see below
|
2336
|
+
(define-syntax ssax:make-parser/positional-args
|
2337
|
+
(syntax-rules ()
|
2338
|
+
((ssax:make-parser/positional-args
|
2339
|
+
*handler-DOCTYPE
|
2340
|
+
*handler-UNDECL-ROOT
|
2341
|
+
*handler-DECL-ROOT
|
2342
|
+
*handler-NEW-LEVEL-SEED
|
2343
|
+
*handler-FINISH-ELEMENT
|
2344
|
+
*handler-CHAR-DATA-HANDLER
|
2345
|
+
*handler-PI)
|
2346
|
+
(lambda (port seed)
|
2347
|
+
|
2348
|
+
; We must've just scanned the DOCTYPE token
|
2349
|
+
; Handle the doctype declaration and exit to
|
2350
|
+
; scan-for-significant-prolog-token-2, and eventually, to the
|
2351
|
+
; element parser.
|
2352
|
+
(define (handle-decl port token-head seed)
|
2353
|
+
(or (eq? (string->symbol "DOCTYPE") token-head)
|
2354
|
+
(parser-error port "XML [22], expected DOCTYPE declaration, found "
|
2355
|
+
token-head))
|
2356
|
+
(assert-curr-char ssax:S-chars "XML [28], space after DOCTYPE" port)
|
2357
|
+
(ssax:skip-S port)
|
2358
|
+
(let*-values
|
2359
|
+
(((docname) (ssax:read-QName port))
|
2360
|
+
((systemid)
|
2361
|
+
(and (ssax:ncname-starting-char? (ssax:skip-S port))
|
2362
|
+
(ssax:read-external-id port)))
|
2363
|
+
((internal-subset?)
|
2364
|
+
(begin (ssax:skip-S port)
|
2365
|
+
(eqv? #\[ (assert-curr-char '(#\> #\[)
|
2366
|
+
"XML [28], end-of-DOCTYPE" port))))
|
2367
|
+
((elems entities namespaces seed)
|
2368
|
+
(*handler-DOCTYPE port docname systemid
|
2369
|
+
internal-subset? seed))
|
2370
|
+
)
|
2371
|
+
(scan-for-significant-prolog-token-2 port elems entities namespaces
|
2372
|
+
seed)))
|
2373
|
+
|
2374
|
+
|
2375
|
+
; Scan the leading PIs until we encounter either a doctype declaration
|
2376
|
+
; or a start token (of the root element)
|
2377
|
+
; In the latter two cases, we exit to the appropriate continuation
|
2378
|
+
(define (scan-for-significant-prolog-token-1 port seed)
|
2379
|
+
(let ((token (ssax:scan-Misc port)))
|
2380
|
+
(if (eof-object? token)
|
2381
|
+
(parser-error port "XML [22], unexpected EOF")
|
2382
|
+
(case (xml-token-kind token)
|
2383
|
+
((PI)
|
2384
|
+
(let ((seed
|
2385
|
+
((ssax:make-pi-parser *handler-PI)
|
2386
|
+
port (xml-token-head token) seed)))
|
2387
|
+
(scan-for-significant-prolog-token-1 port seed)))
|
2388
|
+
((DECL) (handle-decl port (xml-token-head token) seed))
|
2389
|
+
((START)
|
2390
|
+
(let*-values
|
2391
|
+
(((elems entities namespaces seed)
|
2392
|
+
(*handler-UNDECL-ROOT (xml-token-head token) seed)))
|
2393
|
+
(element-parser (xml-token-head token) port elems
|
2394
|
+
entities namespaces #f seed)))
|
2395
|
+
(else (parser-error port "XML [22], unexpected markup "
|
2396
|
+
token))))))
|
2397
|
+
|
2398
|
+
|
2399
|
+
; Scan PIs after the doctype declaration, till we encounter
|
2400
|
+
; the start tag of the root element. After that we exit
|
2401
|
+
; to the element parser
|
2402
|
+
(define (scan-for-significant-prolog-token-2 port elems entities
|
2403
|
+
namespaces seed)
|
2404
|
+
(let ((token (ssax:scan-Misc port)))
|
2405
|
+
(if (eof-object? token)
|
2406
|
+
(parser-error port "XML [22], unexpected EOF")
|
2407
|
+
(case (xml-token-kind token)
|
2408
|
+
((PI)
|
2409
|
+
(let ((seed
|
2410
|
+
((ssax:make-pi-parser *handler-PI)
|
2411
|
+
port (xml-token-head token) seed)))
|
2412
|
+
(scan-for-significant-prolog-token-2 port elems entities
|
2413
|
+
namespaces seed)))
|
2414
|
+
((START)
|
2415
|
+
(element-parser (xml-token-head token) port elems
|
2416
|
+
entities namespaces #f
|
2417
|
+
(*handler-DECL-ROOT (xml-token-head token) seed)))
|
2418
|
+
(else (parser-error port "XML [22], unexpected markup "
|
2419
|
+
token))))))
|
2420
|
+
|
2421
|
+
|
2422
|
+
; A procedure start-tag-head port elems entities namespaces
|
2423
|
+
; preserve-ws? seed
|
2424
|
+
(define element-parser
|
2425
|
+
(ssax:make-elem-parser *handler-NEW-LEVEL-SEED
|
2426
|
+
*handler-FINISH-ELEMENT
|
2427
|
+
*handler-CHAR-DATA-HANDLER
|
2428
|
+
*handler-PI))
|
2429
|
+
|
2430
|
+
; Get the ball rolling ...
|
2431
|
+
(scan-for-significant-prolog-token-1 port seed)
|
2432
|
+
))))
|
2433
|
+
|
2434
|
+
|
2435
|
+
|
2436
|
+
; The following meta-macro turns a regular macro (with positional
|
2437
|
+
; arguments) into a form with keyword (labeled) arguments. We later
|
2438
|
+
; use the meta-macro to convert ssax:make-parser/positional-args into
|
2439
|
+
; ssax:make-parser. The latter provides a prettier (with labeled
|
2440
|
+
; arguments and defaults) interface to
|
2441
|
+
; ssax:make-parser/positional-args
|
2442
|
+
;
|
2443
|
+
; ssax:define-labeled-arg-macro LABELED-ARG-MACRO-NAME
|
2444
|
+
; (POS-MACRO-NAME ARG-DESCRIPTOR ...)
|
2445
|
+
; expands into the definition of a macro
|
2446
|
+
; LABELED-ARG-MACRO-NAME KW-NAME KW-VALUE KW-NAME1 KW-VALUE1 ...
|
2447
|
+
; which, in turn, expands into
|
2448
|
+
; POS-MACRO-NAME ARG1 ARG2 ...
|
2449
|
+
; where each ARG1 etc. comes either from KW-VALUE or from
|
2450
|
+
; the deafult part of ARG-DESCRIPTOR. ARG1 corresponds to the first
|
2451
|
+
; ARG-DESCRIPTOR, ARG2 corresponds to the second descriptor, etc.
|
2452
|
+
; Here ARG-DESCRIPTOR describes one argument of the positional macro.
|
2453
|
+
; It has the form
|
2454
|
+
; (ARG-NAME DEFAULT-VALUE)
|
2455
|
+
; or
|
2456
|
+
; (ARG-NAME)
|
2457
|
+
; In the latter form, the default value is not given, so that the invocation of
|
2458
|
+
; LABELED-ARG-MACRO-NAME must mention the corresponding parameter.
|
2459
|
+
; ARG-NAME can be anything: an identifier, a string, or even a number.
|
2460
|
+
|
2461
|
+
|
2462
|
+
(define-syntax ssax:define-labeled-arg-macro
|
2463
|
+
(syntax-rules ()
|
2464
|
+
((ssax:define-labeled-arg-macro
|
2465
|
+
labeled-arg-macro-name
|
2466
|
+
(positional-macro-name
|
2467
|
+
(arg-name . arg-def) ...))
|
2468
|
+
(define-syntax labeled-arg-macro-name
|
2469
|
+
(syntax-rules ()
|
2470
|
+
((labeled-arg-macro-name . kw-val-pairs)
|
2471
|
+
(letrec-syntax
|
2472
|
+
((find
|
2473
|
+
(syntax-rules (arg-name ...)
|
2474
|
+
((find k-args (arg-name . default) arg-name
|
2475
|
+
val . others) ; found arg-name among kw-val-pairs
|
2476
|
+
(next val . k-args)) ...
|
2477
|
+
((find k-args key arg-no-match-name val . others)
|
2478
|
+
(find k-args key . others))
|
2479
|
+
((find k-args (arg-name default)) ; default must be here
|
2480
|
+
(next default . k-args)) ...
|
2481
|
+
))
|
2482
|
+
(next ; pack the continuation to find
|
2483
|
+
(syntax-rules ()
|
2484
|
+
((next val vals key . keys)
|
2485
|
+
(find ((val . vals) . keys) key . kw-val-pairs))
|
2486
|
+
((next val vals) ; processed all arg-descriptors
|
2487
|
+
(rev-apply (val) vals))))
|
2488
|
+
(rev-apply
|
2489
|
+
(syntax-rules ()
|
2490
|
+
((rev-apply form (x . xs))
|
2491
|
+
(rev-apply (x . form) xs))
|
2492
|
+
((rev-apply form ()) form))))
|
2493
|
+
(next positional-macro-name ()
|
2494
|
+
(arg-name . arg-def) ...))))))))
|
2495
|
+
|
2496
|
+
|
2497
|
+
; The definition of ssax:make-parser
|
2498
|
+
(ssax:define-labeled-arg-macro ssax:make-parser
|
2499
|
+
(ssax:make-parser/positional-args
|
2500
|
+
(DOCTYPE
|
2501
|
+
(lambda (port docname systemid internal-subset? seed)
|
2502
|
+
(when internal-subset?
|
2503
|
+
(ssax:warn port "Internal DTD subset is not currently handled ")
|
2504
|
+
(ssax:skip-internal-dtd port))
|
2505
|
+
(ssax:warn port "DOCTYPE DECL " docname " "
|
2506
|
+
systemid " found and skipped")
|
2507
|
+
(values #f '() '() seed)
|
2508
|
+
))
|
2509
|
+
(UNDECL-ROOT
|
2510
|
+
(lambda (elem-gi seed) (values #f '() '() seed)))
|
2511
|
+
(DECL-ROOT
|
2512
|
+
(lambda (elem-gi seed) seed))
|
2513
|
+
(NEW-LEVEL-SEED) ; required
|
2514
|
+
(FINISH-ELEMENT) ; required
|
2515
|
+
(CHAR-DATA-HANDLER) ; required
|
2516
|
+
(PI ())
|
2517
|
+
))
|
2518
|
+
|
2519
|
+
(run-test
|
2520
|
+
(letrec ((simple-parser
|
2521
|
+
(lambda (str doctype-fn)
|
2522
|
+
(call-with-input-string str
|
2523
|
+
(lambda (port)
|
2524
|
+
((ssax:make-parser
|
2525
|
+
NEW-LEVEL-SEED
|
2526
|
+
(lambda (elem-gi attributes namespaces
|
2527
|
+
expected-content seed)
|
2528
|
+
'())
|
2529
|
+
|
2530
|
+
FINISH-ELEMENT
|
2531
|
+
(lambda (elem-gi attributes namespaces parent-seed seed)
|
2532
|
+
(let
|
2533
|
+
((seed (if (null? namespaces) (reverse seed)
|
2534
|
+
(cons (list '*NAMESPACES* namespaces)
|
2535
|
+
(reverse seed)))))
|
2536
|
+
(let ((seed (if (attlist-null? attributes) seed
|
2537
|
+
(cons
|
2538
|
+
(cons '@
|
2539
|
+
(map (lambda (attr)
|
2540
|
+
(list (car attr) (cdr attr)))
|
2541
|
+
(attlist->alist attributes)))
|
2542
|
+
seed))))
|
2543
|
+
(cons (cons elem-gi seed) parent-seed))))
|
2544
|
+
|
2545
|
+
CHAR-DATA-HANDLER
|
2546
|
+
(lambda (string1 string2 seed)
|
2547
|
+
(if (string-null? string2) (cons string1 seed)
|
2548
|
+
(cons* string2 string1 seed)))
|
2549
|
+
|
2550
|
+
DOCTYPE
|
2551
|
+
(lambda (port docname systemid internal-subset? seed)
|
2552
|
+
(when internal-subset?
|
2553
|
+
(ssax:warn port
|
2554
|
+
"Internal DTD subset is not currently handled ")
|
2555
|
+
(ssax:skip-internal-dtd port))
|
2556
|
+
(ssax:warn port "DOCTYPE DECL " docname " "
|
2557
|
+
systemid " found and skipped")
|
2558
|
+
(doctype-fn docname seed))
|
2559
|
+
|
2560
|
+
UNDECL-ROOT
|
2561
|
+
(lambda (elem-gi seed)
|
2562
|
+
(doctype-fn elem-gi seed))
|
2563
|
+
)
|
2564
|
+
port '())))))
|
2565
|
+
|
2566
|
+
(dummy-doctype-fn (lambda (elem-gi seed) (values #f '() '() seed)))
|
2567
|
+
(test
|
2568
|
+
(lambda (str doctype-fn expected)
|
2569
|
+
(cout nl "Parsing: " str nl)
|
2570
|
+
(let ((result (simple-parser (unesc-string str) doctype-fn)))
|
2571
|
+
(write result)
|
2572
|
+
(assert (equal? result expected)))))
|
2573
|
+
)
|
2574
|
+
|
2575
|
+
(test "<BR/>" dummy-doctype-fn '(('"BR")))
|
2576
|
+
(assert (failed? (test "<BR>" dummy-doctype-fn '())))
|
2577
|
+
(test "<BR></BR>" dummy-doctype-fn '(('"BR")))
|
2578
|
+
(assert (failed? (test "<BR></BB>" dummy-doctype-fn '())))
|
2579
|
+
|
2580
|
+
(test " <A HREF='URL'> link <I>itlink </I> &amp;</A>"
|
2581
|
+
dummy-doctype-fn
|
2582
|
+
'(('"A" (@ ('"HREF" "URL")) " link " ('"I" "itlink ")
|
2583
|
+
" " "&" "amp;")))
|
2584
|
+
|
2585
|
+
(test
|
2586
|
+
" <A HREF='URL' xml:space='preserve'> link <I>itlink </I> &amp;</A>" dummy-doctype-fn
|
2587
|
+
'(('"A" (@ ('"HREF" "URL") (('"xml" . '"space") "preserve"))
|
2588
|
+
" link " ('"I" "itlink ") " " "&" "amp;")))
|
2589
|
+
|
2590
|
+
(test " <A HREF='URL' xml:space='preserve'> link <I xml:space='default'>itlink </I> &amp;</A>" dummy-doctype-fn
|
2591
|
+
'(('"A" (@ ('"HREF" "URL") (('"xml" . '"space") "preserve"))
|
2592
|
+
" link "
|
2593
|
+
('"I" (@ (('"xml" . '"space") "default")) "itlink ")
|
2594
|
+
" " "&" "amp;")))
|
2595
|
+
(test "<itemize><item>This is item 1 </item>%n<!-- Just:a comment --><item>Item 2</item>%n </itemize>" dummy-doctype-fn
|
2596
|
+
`(('"itemize" ('"item" "This is item 1 ")
|
2597
|
+
,(unesc-string "%n") ('"item" "Item 2") ,(unesc-string "%n "))))
|
2598
|
+
(test " <P><![CDATA[<BR>%n<![CDATA[<BR>]]>]]></P>"
|
2599
|
+
dummy-doctype-fn `(('"P" "<BR>" ,nl "<![CDATA[<BR>" "]]" "" ">")))
|
2600
|
+
|
2601
|
+
(test " <P><![CDATA[<BR>%r<![CDATA[<BR>]]>]]></P>"
|
2602
|
+
dummy-doctype-fn `(('"P" "<BR>" ,nl "<![CDATA[<BR>" "]]" "" ">")))
|
2603
|
+
|
2604
|
+
(test "<?xml version='1.0'?>%n%n<Reports TStamp='1'></Reports>"
|
2605
|
+
dummy-doctype-fn '(('"Reports" (@ ('"TStamp" "1")))))
|
2606
|
+
(test "%n<?PI xxx?><!-- Comment %n -%r-->%n<?PI1 zzz?><T/>"
|
2607
|
+
dummy-doctype-fn '(('"T")))
|
2608
|
+
(test "<!DOCTYPE T SYSTEM 'system1' ><!-- comment -->%n<T/>"
|
2609
|
+
(lambda (elem-gi seed) (assert (equal? elem-gi ''"T"))
|
2610
|
+
(values #f '() '() seed))
|
2611
|
+
'(('"T")))
|
2612
|
+
(test "<!DOCTYPE T PUBLIC '//EN/T' \"system1\" [ <!ELEMENT a 'aa'> ]>%n<?pi?><T/>"
|
2613
|
+
(lambda (elem-gi seed) (assert (equal? elem-gi ''"T"))
|
2614
|
+
(values #f '() '() seed))
|
2615
|
+
'(('"T")))
|
2616
|
+
(test "<BR/>"
|
2617
|
+
(lambda (elem-gi seed)
|
2618
|
+
(values '(('"BR" EMPTY ())) '() '() seed)) '(('"BR")))
|
2619
|
+
(test "<BR></BR>"
|
2620
|
+
(lambda (elem-gi seed)
|
2621
|
+
(values '(('"BR" EMPTY ())) '() '() seed)) '(('"BR")))
|
2622
|
+
(assert (failed? (test "<BR>aa</BR>"
|
2623
|
+
(lambda (elem-gi seed)
|
2624
|
+
(values '(('"BR" EMPTY ())) '() '() seed)) '())))
|
2625
|
+
(test "<BR>aa</BR>"
|
2626
|
+
(lambda (elem-gi seed)
|
2627
|
+
(values '(('"BR" PCDATA ())) '() '() seed)) '(('"BR" "aa")))
|
2628
|
+
(assert (failed? (test "<BR>a<I>a</I></BR>"
|
2629
|
+
(lambda (elem-gi seed)
|
2630
|
+
(values '(('"BR" PCDATA ())) '() '() seed)) '())))
|
2631
|
+
(test "<BR>a<I>a</I></BR>"
|
2632
|
+
(lambda (elem-gi seed)
|
2633
|
+
(values '(('"BR" ANY ()) ('"I" PCDATA ())) '() '() seed))
|
2634
|
+
'(('"BR" "a" ('"I" "a"))))
|
2635
|
+
|
2636
|
+
|
2637
|
+
(test "<DIV>Example: \"&example;\"</DIV>"
|
2638
|
+
(lambda (elem-gi seed)
|
2639
|
+
(values #f '((example . "<P>An ampersand (&) may be escaped numerically (&#38;) or with a general entity (&amp;).</P>")) '() seed))
|
2640
|
+
'(('"DIV" "Example: \""
|
2641
|
+
('"P" "An ampersand (" "&" ") may be escaped numerically (" "&" "#38;) or with a general entity (" "&" "amp;).") "\"")))
|
2642
|
+
(test "<DIV>Example: \"&example;\" <P/></DIV>"
|
2643
|
+
(lambda (elem-gi seed)
|
2644
|
+
(values #f '(('"quote" . "<I>example:</I> ex")
|
2645
|
+
('"example" . "<Q>"e;!</Q>?")) '() seed))
|
2646
|
+
'(('"DIV" "Example: \"" ('"Q" ('"I" "example:") " ex" "!") "?"
|
2647
|
+
"\" " ('"P"))))
|
2648
|
+
(assert (failed?
|
2649
|
+
(test "<DIV>Example: \"&example;\" <P/></DIV>"
|
2650
|
+
(lambda (elem-gi seed)
|
2651
|
+
(values #f '(('"quote" . "<I>example:")
|
2652
|
+
('"example" . "<Q>"e;</I>!</Q>?")) '() seed))
|
2653
|
+
'())))
|
2654
|
+
|
2655
|
+
(test "<DIV A:B='A' B='B' xmlns:A='URI1' xmlns='URI1'><A:P xmlns=''><BR/></A:P></DIV>"
|
2656
|
+
(lambda (elem-gi seed)
|
2657
|
+
(values #f '() '() seed))
|
2658
|
+
'((('"URI1" . '"DIV") (@ ('"B" "B") (('"URI1" . '"B") "A"))
|
2659
|
+
(*NAMESPACES* (('"A" '"URI1" . '"URI1")
|
2660
|
+
(*DEFAULT* '"URI1" . '"URI1")))
|
2661
|
+
(('"URI1" . '"P")
|
2662
|
+
(*NAMESPACES* ((*DEFAULT* #f . #f) ('"A" '"URI1" . '"URI1")
|
2663
|
+
(*DEFAULT* '"URI1" . '"URI1")))
|
2664
|
+
('"BR"
|
2665
|
+
(*NAMESPACES* ((*DEFAULT* #f . #f)
|
2666
|
+
('"A" '"URI1" . '"URI1")
|
2667
|
+
(*DEFAULT* '"URI1" . '"URI1"))))))))
|
2668
|
+
(test "<DIV A:B='A' B='B' xmlns:A='URI1' xmlns='URI1'><A:P xmlns=''><BR/></A:P></DIV>"
|
2669
|
+
(lambda (elem-gi seed)
|
2670
|
+
(values #f '() '((#f '"UA" . '"URI1")) seed))
|
2671
|
+
'((('"UA" . '"DIV") (@ ('"B" "B") (('"UA" . '"B") "A"))
|
2672
|
+
(*NAMESPACES* (('"A" '"UA" . '"URI1")
|
2673
|
+
(*DEFAULT* '"UA" . '"URI1") (#f '"UA" . '"URI1")))
|
2674
|
+
(('"UA" . '"P")
|
2675
|
+
(*NAMESPACES* ((*DEFAULT* #f . #f) ('"A" '"UA" . '"URI1")
|
2676
|
+
(*DEFAULT* '"UA" . '"URI1") (#f '"UA" . '"URI1")))
|
2677
|
+
('"BR"
|
2678
|
+
(*NAMESPACES* ((*DEFAULT* #f . #f) ('"A" '"UA" . '"URI1")
|
2679
|
+
(*DEFAULT* '"UA" . '"URI1")
|
2680
|
+
(#f '"UA" . '"URI1"))))))))
|
2681
|
+
; uniqattr should fail
|
2682
|
+
(assert (failed?
|
2683
|
+
(test "<DIV A:B='A' B='B' xmlns:A='URI1' xmlns='URI1'><A:P xmlns=''><BR/></A:P></DIV>"
|
2684
|
+
(lambda (elem-gi seed)
|
2685
|
+
(values
|
2686
|
+
`(('"DIV" ANY (('"B" CDATA IMPLIED #f)
|
2687
|
+
(('"A" . '"B") CDATA IMPLIED #f)
|
2688
|
+
(('"C" . '"B") CDATA IMPLIED "xx")
|
2689
|
+
(('"xmlns" . '"C") CDATA IMPLIED "URI1")
|
2690
|
+
))
|
2691
|
+
(('"A" . '"P") ANY ()) ('"BR" '"EMPTY" ()))
|
2692
|
+
'() '((#f '"UA" . '"URI1")) seed))
|
2693
|
+
'())))
|
2694
|
+
; prefix C undeclared
|
2695
|
+
(assert (failed?
|
2696
|
+
(test "<DIV A:B='A' B='B' xmlns:A='URI1' xmlns='URI1'><A:P xmlns=''><BR/></A:P></DIV>"
|
2697
|
+
(lambda (elem-gi seed)
|
2698
|
+
(values
|
2699
|
+
'(('"DIV" ANY (('"B" CDATA IMPLIED #f)
|
2700
|
+
('"xmlns" CDATA IMPLIED "URI1")
|
2701
|
+
(('"A" . '"B") CDATA IMPLIED #f)
|
2702
|
+
(('"C" . '"B") CDATA IMPLIED "xx")
|
2703
|
+
))
|
2704
|
+
(('"A" . '"P") ANY ()) ('"BR" EMPTY ()))
|
2705
|
+
'() '((#f '"UA" . '"URI1")) seed))
|
2706
|
+
'())))
|
2707
|
+
|
2708
|
+
; contradiction to xmlns declaration
|
2709
|
+
(assert (failed?
|
2710
|
+
(test "<DIV A:B='A' B='B' xmlns:A='URI1' xmlns='URI1'><A:P xmlns=''><BR/></A:P></DIV>"
|
2711
|
+
(lambda (elem-gi seed)
|
2712
|
+
(values
|
2713
|
+
'(('"DIV" ANY (('"B" CDATA IMPLIED #f)
|
2714
|
+
('"xmlns" CDATA FIXED "URI2")
|
2715
|
+
(('"A" . '"B") CDATA IMPLIED #f)
|
2716
|
+
))
|
2717
|
+
(('"A" . '"P") ANY ()) ('"BR" EMPTY ()))
|
2718
|
+
'() '((#f '"UA" . '"URI1")) seed))
|
2719
|
+
'())))
|
2720
|
+
|
2721
|
+
(test "<DIV A:B='A' B='B' xmlns:A='URI1' xmlns='URI1'><A:P xmlns=''><BR/></A:P></DIV>"
|
2722
|
+
(lambda (elem-gi seed)
|
2723
|
+
(values
|
2724
|
+
'(('"DIV" ANY (('"B" CDATA IMPLIED #f)
|
2725
|
+
('"xmlns" CDATA FIXED "URI1")
|
2726
|
+
(('"A" . '"B") CDATA IMPLIED #f)
|
2727
|
+
))
|
2728
|
+
(('"A" . '"P") ANY ()) ('"BR" EMPTY ()))
|
2729
|
+
'() '((#f '"UA" . '"URI1")) seed))
|
2730
|
+
'((('"UA" . '"DIV") (@ ('"B" "B") (('"UA" . '"B") "A"))
|
2731
|
+
(*NAMESPACES* ((*DEFAULT* '"UA" . '"URI1")
|
2732
|
+
('"A" '"UA" . '"URI1") (#f '"UA" . '"URI1")))
|
2733
|
+
(('"UA" . '"P")
|
2734
|
+
(*NAMESPACES* ((*DEFAULT* #f . #f)
|
2735
|
+
(*DEFAULT* '"UA" . '"URI1")
|
2736
|
+
('"A" '"UA" . '"URI1") (#f '"UA" . '"URI1")))
|
2737
|
+
('"BR"
|
2738
|
+
(*NAMESPACES* ((*DEFAULT* #f . #f) (*DEFAULT* '"UA" . '"URI1")
|
2739
|
+
('"A" '"UA" . '"URI1") (#f '"UA" . '"URI1"))))))))
|
2740
|
+
|
2741
|
+
(test "<DIV A:B='A' B='B' xmlns:A='URI1' xmlns='URI1'><A:P xmlns=''><BR/></A:P></DIV>"
|
2742
|
+
(lambda (elem-gi seed)
|
2743
|
+
(values
|
2744
|
+
'(('"DIV" ANY (('"B" CDATA IMPLIED #f)
|
2745
|
+
(('"A" . '"B") CDATA IMPLIED #f)
|
2746
|
+
(('"C" . '"B") CDATA IMPLIED "xx")
|
2747
|
+
(('"xmlns" . '"C") CDATA IMPLIED "URI2")
|
2748
|
+
))
|
2749
|
+
(('"A" . '"P") ANY ()) ('"BR" EMPTY ()))
|
2750
|
+
'() '((#f '"UA" . '"URI1")) seed))
|
2751
|
+
'((('"UA" . '"DIV") (@ ('"B" "B") (('"UA" . '"B") "A")
|
2752
|
+
(('"URI2" . '"B") "xx"))
|
2753
|
+
(*NAMESPACES* ((*DEFAULT* '"UA" . '"URI1")
|
2754
|
+
('"A" '"UA" . '"URI1")
|
2755
|
+
('"C" '"URI2" . '"URI2")
|
2756
|
+
(#f '"UA" . '"URI1")))
|
2757
|
+
(('"UA" . '"P")
|
2758
|
+
(*NAMESPACES* ((*DEFAULT* #f . #f) (*DEFAULT* '"UA" . '"URI1")
|
2759
|
+
('"A" '"UA" . '"URI1")
|
2760
|
+
('"C" '"URI2" . '"URI2") (#f '"UA" . '"URI1")))
|
2761
|
+
('"BR"
|
2762
|
+
(*NAMESPACES* ((*DEFAULT* #f . #f)
|
2763
|
+
(*DEFAULT* '"UA" . '"URI1")
|
2764
|
+
('"A" '"UA" . '"URI1")
|
2765
|
+
('"C" '"URI2" . '"URI2")
|
2766
|
+
(#f '"UA" . '"URI1"))))))))
|
2767
|
+
))
|
2768
|
+
|
2769
|
+
|
2770
|
+
|
2771
|
+
;========================================================================
|
2772
|
+
; Highest-level parsers: XML to SXML
|
2773
|
+
;
|
2774
|
+
|
2775
|
+
; First, a few utility procedures that turned out useful
|
2776
|
+
|
2777
|
+
; ssax:reverse-collect-str LIST-OF-FRAGS -> LIST-OF-FRAGS
|
2778
|
+
; given the list of fragments (some of which are text strings)
|
2779
|
+
; reverse the list and concatenate adjacent text strings.
|
2780
|
+
; We can prove from the general case below that if LIST-OF-FRAGS
|
2781
|
+
; has zero or one element, the result of the procedure is equal?
|
2782
|
+
; to its argument. This fact justifies the shortcut evaluation below.
|
2783
|
+
(define (ssax:reverse-collect-str fragments)
|
2784
|
+
(cond
|
2785
|
+
((null? fragments) '()) ; a shortcut
|
2786
|
+
((null? (cdr fragments)) fragments) ; see the comment above
|
2787
|
+
(else
|
2788
|
+
(let loop ((fragments fragments) (result '()) (strs '()))
|
2789
|
+
(cond
|
2790
|
+
((null? fragments)
|
2791
|
+
(if (null? strs) result
|
2792
|
+
(cons (string-concatenate/shared strs) result)))
|
2793
|
+
((string? (car fragments))
|
2794
|
+
(loop (cdr fragments) result (cons (car fragments) strs)))
|
2795
|
+
(else
|
2796
|
+
(loop (cdr fragments)
|
2797
|
+
(cons
|
2798
|
+
(car fragments)
|
2799
|
+
(if (null? strs) result
|
2800
|
+
(cons (string-concatenate/shared strs) result)))
|
2801
|
+
'())))))))
|
2802
|
+
|
2803
|
+
|
2804
|
+
; ssax:reverse-collect-str-drop-ws LIST-OF-FRAGS -> LIST-OF-FRAGS
|
2805
|
+
; given the list of fragments (some of which are text strings)
|
2806
|
+
; reverse the list and concatenate adjacent text strings.
|
2807
|
+
; We also drop "unsignificant" whitespace, that is, whitespace
|
2808
|
+
; in front, behind and between elements. The whitespace that
|
2809
|
+
; is included in character data is not affected.
|
2810
|
+
; We use this procedure to "intelligently" drop "insignificant"
|
2811
|
+
; whitespace in the parsed SXML. If the strict compliance with
|
2812
|
+
; the XML Recommendation regarding the whitespace is desired, please
|
2813
|
+
; use the ssax:reverse-collect-str procedure instead.
|
2814
|
+
|
2815
|
+
(define (ssax:reverse-collect-str-drop-ws fragments)
|
2816
|
+
(cond
|
2817
|
+
((null? fragments) '()) ; a shortcut
|
2818
|
+
((null? (cdr fragments)) ; another shortcut
|
2819
|
+
(if (and (string? (car fragments)) (string-whitespace? (car fragments)))
|
2820
|
+
'() fragments)) ; remove trailing ws
|
2821
|
+
(else
|
2822
|
+
(let loop ((fragments fragments) (result '()) (strs '())
|
2823
|
+
(all-whitespace? #t))
|
2824
|
+
(cond
|
2825
|
+
((null? fragments)
|
2826
|
+
(if all-whitespace? result ; remove leading ws
|
2827
|
+
(cons (string-concatenate/shared strs) result)))
|
2828
|
+
((string? (car fragments))
|
2829
|
+
(loop (cdr fragments) result (cons (car fragments) strs)
|
2830
|
+
(and all-whitespace?
|
2831
|
+
(string-whitespace? (car fragments)))))
|
2832
|
+
(else
|
2833
|
+
(loop (cdr fragments)
|
2834
|
+
(cons
|
2835
|
+
(car fragments)
|
2836
|
+
(if all-whitespace? result
|
2837
|
+
(cons (string-concatenate/shared strs) result)))
|
2838
|
+
'() #t)))))))
|
2839
|
+
|
2840
|
+
|
2841
|
+
; procedure: ssax:xml->sxml PORT NAMESPACE-PREFIX-ASSIG
|
2842
|
+
;
|
2843
|
+
; This is an instance of a SSAX parser above that returns an SXML
|
2844
|
+
; representation of the XML document to be read from PORT.
|
2845
|
+
; NAMESPACE-PREFIX-ASSIG is a list of (USER-PREFIX . URI-STRING)
|
2846
|
+
; that assigns USER-PREFIXes to certain namespaces identified by
|
2847
|
+
; particular URI-STRINGs. It may be an empty list.
|
2848
|
+
; The procedure returns an SXML tree. The port points out to the
|
2849
|
+
; first character after the root element.
|
2850
|
+
|
2851
|
+
(define (ssax:xml->sxml port namespace-prefix-assig)
|
2852
|
+
(letrec
|
2853
|
+
((namespaces
|
2854
|
+
(map (lambda (el)
|
2855
|
+
(cons* #f (car el) (ssax:uri-string->symbol (cdr el))))
|
2856
|
+
namespace-prefix-assig))
|
2857
|
+
|
2858
|
+
(RES-NAME->SXML
|
2859
|
+
(lambda (res-name)
|
2860
|
+
(string->symbol
|
2861
|
+
(string-append
|
2862
|
+
(symbol->string (car res-name))
|
2863
|
+
":"
|
2864
|
+
(symbol->string (cdr res-name))))))
|
2865
|
+
|
2866
|
+
)
|
2867
|
+
(let ((result
|
2868
|
+
(reverse
|
2869
|
+
((ssax:make-parser
|
2870
|
+
NEW-LEVEL-SEED
|
2871
|
+
(lambda (elem-gi attributes namespaces
|
2872
|
+
expected-content seed)
|
2873
|
+
'())
|
2874
|
+
|
2875
|
+
FINISH-ELEMENT
|
2876
|
+
(lambda (elem-gi attributes namespaces parent-seed seed)
|
2877
|
+
(let ((seed (ssax:reverse-collect-str seed))
|
2878
|
+
(attrs
|
2879
|
+
(attlist-fold
|
2880
|
+
(lambda (attr accum)
|
2881
|
+
(cons (list
|
2882
|
+
(if (symbol? (car attr)) (car attr)
|
2883
|
+
(RES-NAME->SXML (car attr)))
|
2884
|
+
(cdr attr)) accum))
|
2885
|
+
'() attributes)))
|
2886
|
+
(cons
|
2887
|
+
(cons
|
2888
|
+
(if (symbol? elem-gi) elem-gi
|
2889
|
+
(RES-NAME->SXML elem-gi))
|
2890
|
+
(if (null? attrs) seed
|
2891
|
+
(cons (cons '@ attrs) seed)))
|
2892
|
+
parent-seed)))
|
2893
|
+
|
2894
|
+
CHAR-DATA-HANDLER
|
2895
|
+
(lambda (string1 string2 seed)
|
2896
|
+
(if (string-null? string2) (cons string1 seed)
|
2897
|
+
(cons* string2 string1 seed)))
|
2898
|
+
|
2899
|
+
DOCTYPE
|
2900
|
+
(lambda (port docname systemid internal-subset? seed)
|
2901
|
+
(when internal-subset?
|
2902
|
+
(ssax:warn port
|
2903
|
+
"Internal DTD subset is not currently handled ")
|
2904
|
+
(ssax:skip-internal-dtd port))
|
2905
|
+
(ssax:warn port "DOCTYPE DECL " docname " "
|
2906
|
+
systemid " found and skipped")
|
2907
|
+
(values #f '() namespaces seed))
|
2908
|
+
|
2909
|
+
UNDECL-ROOT
|
2910
|
+
(lambda (elem-gi seed)
|
2911
|
+
(values #f '() namespaces seed))
|
2912
|
+
|
2913
|
+
PI
|
2914
|
+
((*DEFAULT* .
|
2915
|
+
(lambda (port pi-tag seed)
|
2916
|
+
(cons
|
2917
|
+
(list '*PI* pi-tag (ssax:read-pi-body-as-string port))
|
2918
|
+
seed))))
|
2919
|
+
)
|
2920
|
+
port '()))))
|
2921
|
+
(cons '*TOP*
|
2922
|
+
(if (null? namespace-prefix-assig) result
|
2923
|
+
(cons
|
2924
|
+
(list '@ (cons '*NAMESPACES*
|
2925
|
+
(map (lambda (ns) (list (car ns) (cdr ns)))
|
2926
|
+
namespace-prefix-assig)))
|
2927
|
+
result)))
|
2928
|
+
)))
|
2929
|
+
|
2930
|
+
; For backwards compatibility
|
2931
|
+
(define SSAX:XML->SXML ssax:xml->sxml)
|
2932
|
+
|
2933
|
+
|
2934
|
+
; a few lines of validation code
|
2935
|
+
(run-test (letrec
|
2936
|
+
((test (lambda (str namespace-assig expected-res)
|
2937
|
+
(newline) (display "input: ")
|
2938
|
+
(write (unesc-string str)) (newline) (display "Result: ")
|
2939
|
+
(let ((result
|
2940
|
+
(call-with-input-string (unesc-string str)
|
2941
|
+
(lambda (port)
|
2942
|
+
(ssax:xml->sxml port namespace-assig)))))
|
2943
|
+
(pp result)
|
2944
|
+
(assert (equal_? result expected-res))))))
|
2945
|
+
|
2946
|
+
(test " <BR/>" '() '(*TOP* (BR)))
|
2947
|
+
(test "<BR></BR>" '() '(*TOP* (BR)))
|
2948
|
+
(test " <BR CLEAR='ALL'%nCLASS='Class1'/>" '()
|
2949
|
+
'(*TOP* (BR (@ (CLEAR "ALL") (CLASS "Class1")))))
|
2950
|
+
(test " <A HREF='URL'> link <I>itlink </I> &amp;</A>" '()
|
2951
|
+
'(*TOP* (A (@ (HREF "URL")) " link " (I "itlink ") " &")))
|
2952
|
+
(test " <A HREF='URL' xml:space='preserve'> link <I>itlink </I> &amp;</A>" '()
|
2953
|
+
'(*TOP* (A (@ (xml:space "preserve") (HREF "URL"))
|
2954
|
+
" link " (I "itlink ") " &")))
|
2955
|
+
(test " <A HREF='URL' xml:space='preserve'> link <I xml:space='default'>itlink </I> &amp;</A>" '()
|
2956
|
+
'(*TOP* (A (@ (xml:space "preserve") (HREF "URL"))
|
2957
|
+
" link " (I (@ (xml:space "default"))
|
2958
|
+
"itlink ") " &")))
|
2959
|
+
(test " <P><?pi1 p1 content ?>?<?pi2 pi2? content? ??></P>" '()
|
2960
|
+
'(*TOP* (P (*PI* pi1 "p1 content ") "?"
|
2961
|
+
(*PI* pi2 "pi2? content? ?"))))
|
2962
|
+
(test " <P>some text <![CDATA[<]]>1%n"<B>strong</B>"%r</P>"
|
2963
|
+
'()
|
2964
|
+
`(*TOP* (P ,(unesc-string "some text <1%n\"")
|
2965
|
+
(B "strong") ,(unesc-string "\"%n"))))
|
2966
|
+
(test " <P><![CDATA[<BR>%n<![CDATA[<BR>]]>]]></P>" '()
|
2967
|
+
`(*TOP* (P ,(unesc-string "<BR>%n<![CDATA[<BR>]]>"))))
|
2968
|
+
; (test "<T1><T2>it's%r%nand that%n</T2>%r%n%r%n%n</T1>" '()
|
2969
|
+
; '(*TOP* (T1 (T2 "it's%nand that%n") "%n%n%n")))
|
2970
|
+
(test "<T1><T2>it's%r%nand that%n</T2>%r%n%r%n%n</T1>" '()
|
2971
|
+
`(*TOP* (T1 (T2 ,(unesc-string "it's%nand that%n")) ,(unesc-string "%n%n%n"))))
|
2972
|
+
(test "<T1><T2>it's%rand that%n</T2>%r%n%r%n%n</T1>" '()
|
2973
|
+
`(*TOP* (T1 (T2 ,(unesc-string "it's%nand that%n")) ,(unesc-string "%n%n%n"))))
|
2974
|
+
(test "<!DOCTYPE T SYSTEM 'system1' ><!-- comment -->%n<T/>" '()
|
2975
|
+
'(*TOP* (T)))
|
2976
|
+
(test "<?xml version='1.0'?>%n<WEIGHT unit=\"pound\">%n<NET certified='certified'> 67 </NET>%n<GROSS> 95 </GROSS>%n</WEIGHT>" '()
|
2977
|
+
`(*TOP* (*PI* xml "version='1.0'") (WEIGHT (@ (unit "pound"))
|
2978
|
+
,nl (NET (@ (certified "certified")) " 67 ") ,nl
|
2979
|
+
(GROSS " 95 ") ,nl)
|
2980
|
+
))
|
2981
|
+
; (test "<?xml version='1.0'?>%n<WEIGHT unit=\"pound\">%n<NET certified='certified'> 67 </NET>%n<GROSS> 95 </GROSS>%n</WEIGHT>" '()
|
2982
|
+
; '(*TOP* (*PI* xml "version='1.0'") (WEIGHT (@ (unit "pound"))
|
2983
|
+
; "%n" (NET (@ (certified "certified")) " 67 ")
|
2984
|
+
; "%n" (GROSS " 95 ") "%n")
|
2985
|
+
; ))
|
2986
|
+
(test "<DIV A:B='A' B='B' xmlns:A='URI1' xmlns='URI1'><A:P xmlns=''><BR/></A:P></DIV>" '()
|
2987
|
+
'(*TOP* (URI1:DIV (@ (URI1:B "A") (B "B")) (URI1:P (BR)))))
|
2988
|
+
(test "<DIV A:B='A' B='B' xmlns:A='URI1' xmlns='URI1'><A:P xmlns=''><BR/></A:P></DIV>" '((UA . "URI1"))
|
2989
|
+
'(*TOP* (@ (*NAMESPACES* (UA "URI1")))
|
2990
|
+
(UA:DIV (@ (UA:B "A") (B "B")) (UA:P (BR)))))
|
2991
|
+
|
2992
|
+
; A few tests from XML Namespaces Recommendation
|
2993
|
+
(test (string-append
|
2994
|
+
"<x xmlns:edi='http://ecommerce.org/schema'>"
|
2995
|
+
"<!-- the 'taxClass' attribute's ns http://ecommerce.org/schema -->"
|
2996
|
+
"<lineItem edi:taxClass='exempt'>Baby food</lineItem>" nl
|
2997
|
+
"</x>") '()
|
2998
|
+
`(*TOP*
|
2999
|
+
(x (lineItem
|
3000
|
+
(@ (http://ecommerce.org/schema:taxClass "exempt"))
|
3001
|
+
"Baby food") ,nl)))
|
3002
|
+
(test (string-append
|
3003
|
+
"<x xmlns:edi='http://ecommerce.org/schema'>"
|
3004
|
+
"<!-- the 'taxClass' attribute's ns http://ecommerce.org/schema -->"
|
3005
|
+
"<lineItem edi:taxClass='exempt'>Baby food</lineItem>"
|
3006
|
+
"</x>") '((EDI . "http://ecommerce.org/schema"))
|
3007
|
+
'(*TOP*
|
3008
|
+
(@ (*NAMESPACES* (EDI "http://ecommerce.org/schema")))
|
3009
|
+
(x (lineItem
|
3010
|
+
(@ (EDI:taxClass "exempt"))
|
3011
|
+
"Baby food"))))
|
3012
|
+
|
3013
|
+
(test (string-append
|
3014
|
+
"<bk:book xmlns:bk='urn:loc.gov:books' "
|
3015
|
+
"xmlns:isbn='urn:ISBN:0-395-36341-6'>"
|
3016
|
+
"<bk:title>Cheaper by the Dozen</bk:title>"
|
3017
|
+
"<isbn:number>1568491379</isbn:number></bk:book>")
|
3018
|
+
'()
|
3019
|
+
'(*TOP* (urn:loc.gov:books:book
|
3020
|
+
(urn:loc.gov:books:title "Cheaper by the Dozen")
|
3021
|
+
(urn:ISBN:0-395-36341-6:number "1568491379"))))
|
3022
|
+
|
3023
|
+
(test (string-append
|
3024
|
+
"<!-- initially, the default namespace is 'books' -->"
|
3025
|
+
"<book xmlns='urn:loc.gov:books' "
|
3026
|
+
"xmlns:isbn='urn:ISBN:0-395-36341-6'>"
|
3027
|
+
"<title>Cheaper by the Dozen</title>"
|
3028
|
+
"<isbn:number>1568491379</isbn:number>"
|
3029
|
+
"<notes>"
|
3030
|
+
"<!-- make HTML the default namespace for some commentary -->"
|
3031
|
+
"<p xmlns='urn:w3-org-ns:HTML'>"
|
3032
|
+
"This is a <i>funny</i> book!"
|
3033
|
+
"</p>"
|
3034
|
+
"</notes>"
|
3035
|
+
"</book>") '()
|
3036
|
+
'(*TOP* (urn:loc.gov:books:book
|
3037
|
+
(urn:loc.gov:books:title "Cheaper by the Dozen")
|
3038
|
+
(urn:ISBN:0-395-36341-6:number "1568491379")
|
3039
|
+
(urn:loc.gov:books:notes
|
3040
|
+
(urn:w3-org-ns:HTML:p
|
3041
|
+
"This is a " (urn:w3-org-ns:HTML:i "funny")
|
3042
|
+
" book!")))))
|
3043
|
+
|
3044
|
+
(test (string-append
|
3045
|
+
"<Beers>"
|
3046
|
+
"<!-- the default namespace is now that of HTML -->"
|
3047
|
+
"<table xmlns='http://www.w3.org/TR/REC-html40'>"
|
3048
|
+
"<th><td>Name</td><td>Origin</td><td>Description</td></th>"
|
3049
|
+
"<tr>"
|
3050
|
+
"<!-- no default namespace inside table cells -->"
|
3051
|
+
"<td><brandName xmlns=\"\">Huntsman</brandName></td>"
|
3052
|
+
"<td><origin xmlns=''>Bath, UK</origin></td>"
|
3053
|
+
"<td>"
|
3054
|
+
"<details xmlns=''><class>Bitter</class><hop>Fuggles</hop>"
|
3055
|
+
"<pro>Wonderful hop, light alcohol, good summer beer</pro>"
|
3056
|
+
"<con>Fragile; excessive variance pub to pub</con>"
|
3057
|
+
"</details>"
|
3058
|
+
"</td>"
|
3059
|
+
"</tr>"
|
3060
|
+
"</table>"
|
3061
|
+
"</Beers>")
|
3062
|
+
'((html . "http://www.w3.org/TR/REC-html40"))
|
3063
|
+
'(*TOP*
|
3064
|
+
(@ (*NAMESPACES* (html "http://www.w3.org/TR/REC-html40")))
|
3065
|
+
(Beers (html:table
|
3066
|
+
(html:th (html:td "Name")
|
3067
|
+
(html:td "Origin")
|
3068
|
+
(html:td "Description"))
|
3069
|
+
(html:tr (html:td (brandName "Huntsman"))
|
3070
|
+
(html:td (origin "Bath, UK"))
|
3071
|
+
(html:td
|
3072
|
+
(details
|
3073
|
+
(class "Bitter")
|
3074
|
+
(hop "Fuggles")
|
3075
|
+
(pro "Wonderful hop, light alcohol, good summer beer")
|
3076
|
+
(con "Fragile; excessive variance pub to pub"))))))))
|
3077
|
+
|
3078
|
+
(test (string-append
|
3079
|
+
"<!-- 1 --><RESERVATION xmlns:HTML='http://www.w3.org/TR/REC-html40'>"
|
3080
|
+
"<!-- 2 --><NAME HTML:CLASS=\"largeSansSerif\">Layman, A</NAME>"
|
3081
|
+
"<!-- 3 --><SEAT CLASS='Y' HTML:CLASS=\"largeMonotype\">33B</SEAT>"
|
3082
|
+
"<!-- 4 --><HTML:A HREF='/cgi-bin/ResStatus'>Check Status</HTML:A>"
|
3083
|
+
"<!-- 5 --><DEPARTURE>1997-05-24T07:55:00+1</DEPARTURE></RESERVATION>")
|
3084
|
+
'((HTML . "http://www.w3.org/TR/REC-html40"))
|
3085
|
+
'(*TOP*
|
3086
|
+
(@ (*NAMESPACES* (HTML "http://www.w3.org/TR/REC-html40")))
|
3087
|
+
(RESERVATION
|
3088
|
+
(NAME (@ (HTML:CLASS "largeSansSerif")) "Layman, A")
|
3089
|
+
(SEAT (@ (HTML:CLASS "largeMonotype") (CLASS "Y")) "33B")
|
3090
|
+
(HTML:A (@ (HREF "/cgi-bin/ResStatus")) "Check Status")
|
3091
|
+
(DEPARTURE "1997-05-24T07:55:00+1"))))
|
3092
|
+
; Part of RDF from the XML Infoset
|
3093
|
+
(test (string-concatenate/shared '(
|
3094
|
+
"<?xml version='1.0' encoding='utf-8' standalone='yes'?>"
|
3095
|
+
"<!-- this can be decoded as US-ASCII or iso-8859-1 as well,"
|
3096
|
+
" since it contains no characters outside the US-ASCII repertoire -->"
|
3097
|
+
"<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'"
|
3098
|
+
" xmlns:rdfs='http://www.w3.org/2000/01/rdf-schema#'"
|
3099
|
+
" xmlns='http://www.w3.org/2001/02/infoset#'>"
|
3100
|
+
"<rdfs:Class ID='Boolean'/>"
|
3101
|
+
"<Boolean ID='Boolean.true'/>"
|
3102
|
+
"<Boolean ID='Boolean.false'/>"
|
3103
|
+
"<!--Info item classes-->"
|
3104
|
+
"<rdfs:Class ID='InfoItem'/>"
|
3105
|
+
"<rdfs:Class ID='Document' rdfs:subClassOf='#InfoItem'/>"
|
3106
|
+
"<rdfs:Class ID='Element' rdfs:subClassOf='#InfoItem'/>"
|
3107
|
+
"<rdfs:Class ID='Attribute' rdfs:subClassOf='#InfoItem'/>"
|
3108
|
+
"<rdfs:Class ID='InfoItemSet'
|
3109
|
+
rdfs:subClassOf='http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag'/>"
|
3110
|
+
"<rdfs:Class ID='AttributeSet' rdfs:subClassOf='#InfoItemSet'/>"
|
3111
|
+
"<!--Info item properties-->"
|
3112
|
+
"<rdfs:Property ID='allDeclarationsProcessed'>"
|
3113
|
+
"<rdfs:domain resource='#Document'/>"
|
3114
|
+
"<rdfs:range resource='#Boolean'/></rdfs:Property>"
|
3115
|
+
"<rdfs:Property ID='attributes'>"
|
3116
|
+
"<rdfs:domain resource='#Element'/>"
|
3117
|
+
"<rdfs:range resource='#AttributeSet'/>"
|
3118
|
+
"</rdfs:Property>"
|
3119
|
+
"</rdf:RDF>"))
|
3120
|
+
'((RDF . "http://www.w3.org/1999/02/22-rdf-syntax-ns#")
|
3121
|
+
(RDFS . "http://www.w3.org/2000/01/rdf-schema#")
|
3122
|
+
(ISET . "http://www.w3.org/2001/02/infoset#"))
|
3123
|
+
'(*TOP* (@ (*NAMESPACES*
|
3124
|
+
(RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#")
|
3125
|
+
(RDFS "http://www.w3.org/2000/01/rdf-schema#")
|
3126
|
+
(ISET "http://www.w3.org/2001/02/infoset#")))
|
3127
|
+
(*PI* xml "version='1.0' encoding='utf-8' standalone='yes'")
|
3128
|
+
(RDF:RDF
|
3129
|
+
(RDFS:Class (@ (ID "Boolean")))
|
3130
|
+
(ISET:Boolean (@ (ID "Boolean.true")))
|
3131
|
+
(ISET:Boolean (@ (ID "Boolean.false")))
|
3132
|
+
(RDFS:Class (@ (ID "InfoItem")))
|
3133
|
+
(RDFS:Class (@ (RDFS:subClassOf "#InfoItem") (ID "Document")))
|
3134
|
+
(RDFS:Class (@ (RDFS:subClassOf "#InfoItem") (ID "Element")))
|
3135
|
+
(RDFS:Class (@ (RDFS:subClassOf "#InfoItem") (ID "Attribute")))
|
3136
|
+
(RDFS:Class
|
3137
|
+
(@ (RDFS:subClassOf
|
3138
|
+
"http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag")
|
3139
|
+
(ID "InfoItemSet")))
|
3140
|
+
(RDFS:Class
|
3141
|
+
(@ (RDFS:subClassOf "#InfoItemSet") (ID "AttributeSet")))
|
3142
|
+
(RDFS:Property
|
3143
|
+
(@ (ID "allDeclarationsProcessed"))
|
3144
|
+
(RDFS:domain (@ (resource "#Document")))
|
3145
|
+
(RDFS:range (@ (resource "#Boolean"))))
|
3146
|
+
(RDFS:Property
|
3147
|
+
(@ (ID "attributes"))
|
3148
|
+
(RDFS:domain (@ (resource "#Element")))
|
3149
|
+
(RDFS:range (@ (resource "#AttributeSet")))))))
|
3150
|
+
|
3151
|
+
; Part of RDF from RSS of the Daemon News Mall
|
3152
|
+
(test (string-concatenate/shared (list-intersperse '(
|
3153
|
+
"<?xml version='1.0'?><rdf:RDF "
|
3154
|
+
"xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' "
|
3155
|
+
"xmlns='http://my.netscape.com/rdf/simple/0.9/'>"
|
3156
|
+
"<channel>"
|
3157
|
+
"<title>Daemon News Mall</title>"
|
3158
|
+
"<link>http://mall.daemonnews.org/</link>"
|
3159
|
+
"<description>Central source for all your BSD needs</description>"
|
3160
|
+
"</channel>"
|
3161
|
+
"<item>"
|
3162
|
+
"<title>Daemon News Jan/Feb Issue NOW Available! Subscribe $24.95</title>"
|
3163
|
+
"<link>http://mall.daemonnews.org/?page=shop/flypage&product_id=880</link>"
|
3164
|
+
"</item>"
|
3165
|
+
"<item>"
|
3166
|
+
"<title>The Design and Implementation of the 4.4BSD Operating System $54.95</title>"
|
3167
|
+
"<link>http://mall.daemonnews.org/?page=shop/flypage&product_id=912&category_id=1761</link>"
|
3168
|
+
"</item>"
|
3169
|
+
"</rdf:RDF>")
|
3170
|
+
(string #\newline)
|
3171
|
+
))
|
3172
|
+
'((RDF . "http://www.w3.org/1999/02/22-rdf-syntax-ns#")
|
3173
|
+
(RSS . "http://my.netscape.com/rdf/simple/0.9/")
|
3174
|
+
(ISET . "http://www.w3.org/2001/02/infoset#"))
|
3175
|
+
`(*TOP* (@ (*NAMESPACES*
|
3176
|
+
(RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#")
|
3177
|
+
(RSS "http://my.netscape.com/rdf/simple/0.9/")
|
3178
|
+
(ISET "http://www.w3.org/2001/02/infoset#")))
|
3179
|
+
(*PI* xml "version='1.0'")
|
3180
|
+
(RDF:RDF ,nl
|
3181
|
+
(RSS:channel ,nl
|
3182
|
+
(RSS:title "Daemon News Mall") ,nl
|
3183
|
+
(RSS:link "http://mall.daemonnews.org/") ,nl
|
3184
|
+
(RSS:description "Central source for all your BSD needs") ,nl) ,nl
|
3185
|
+
(RSS:item ,nl
|
3186
|
+
(RSS:title
|
3187
|
+
"Daemon News Jan/Feb Issue NOW Available! Subscribe $24.95") ,nl
|
3188
|
+
(RSS:link
|
3189
|
+
"http://mall.daemonnews.org/?page=shop/flypage&product_id=880") ,nl) ,nl
|
3190
|
+
(RSS:item ,nl
|
3191
|
+
(RSS:title
|
3192
|
+
"The Design and Implementation of the 4.4BSD Operating System $54.95") ,nl
|
3193
|
+
(RSS:link
|
3194
|
+
"http://mall.daemonnews.org/?page=shop/flypage&product_id=912&category_id=1761") ,nl) ,nl)))
|
3195
|
+
|
3196
|
+
(test (string-concatenate/shared
|
3197
|
+
'("<Forecasts TStamp='958082142'>"
|
3198
|
+
"<TAF TStamp='958066200' LatLon='36.583, -121.850' BId='724915'"
|
3199
|
+
" SName='KMRY, MONTEREY PENINSULA'>"
|
3200
|
+
"<VALID TRange='958068000, 958154400'>111730Z 111818</VALID>"
|
3201
|
+
"<PERIOD TRange='958068000, 958078800'>"
|
3202
|
+
"<PREVAILING>31010KT P6SM FEW030</PREVAILING>"
|
3203
|
+
"</PERIOD>"
|
3204
|
+
"<PERIOD TRange='958078800, 958104000' Title='FM2100'>"
|
3205
|
+
"<PREVAILING>29016KT P6SM FEW040</PREVAILING>"
|
3206
|
+
"</PERIOD>"
|
3207
|
+
"<PERIOD TRange='958104000, 958154400' Title='FM0400'>"
|
3208
|
+
"<PREVAILING>29010KT P6SM SCT200</PREVAILING>"
|
3209
|
+
"<VAR Title='BECMG 0708' TRange='958114800, 958118400'>VRB05KT</VAR>"
|
3210
|
+
"</PERIOD></TAF>"
|
3211
|
+
"</Forecasts>"))
|
3212
|
+
'()
|
3213
|
+
'(*TOP* (Forecasts
|
3214
|
+
(@ (TStamp "958082142"))
|
3215
|
+
(TAF (@ (TStamp "958066200")
|
3216
|
+
(SName "KMRY, MONTEREY PENINSULA")
|
3217
|
+
(LatLon "36.583, -121.850")
|
3218
|
+
(BId "724915"))
|
3219
|
+
(VALID (@ (TRange "958068000, 958154400")) "111730Z 111818")
|
3220
|
+
(PERIOD (@ (TRange "958068000, 958078800"))
|
3221
|
+
(PREVAILING "31010KT P6SM FEW030"))
|
3222
|
+
(PERIOD (@ (Title "FM2100") (TRange "958078800, 958104000"))
|
3223
|
+
(PREVAILING "29016KT P6SM FEW040"))
|
3224
|
+
(PERIOD (@ (Title "FM0400") (TRange "958104000, 958154400"))
|
3225
|
+
(PREVAILING "29010KT P6SM SCT200")
|
3226
|
+
(VAR (@ (Title "BECMG 0708")
|
3227
|
+
(TRange "958114800, 958118400"))
|
3228
|
+
"VRB05KT"))))))
|
3229
|
+
))
|
3230
|
+
|
3231
|
+
(run-test
|
3232
|
+
(newline)
|
3233
|
+
(display "All tests passed")
|
3234
|
+
(newline)
|
3235
|
+
)
|