Beispiel #1
0
def import_sheet(doc):
	#print "Import!", doc

	root = Program('XSLT')

	# The root program puts the mark on the Result node and the cursor on the Source.
	# It then runs the program for the default mode. There is one program for each mode, and
	# it acts as a dispatcher. It finds a template which matches the cursor node and runs
	# the program for that template.

	op = add(root.code.start, 'do_search', '/xslt/Result')
	op = add(op, 'mark_selection')
	op = add(op, 'do_search', '/xslt/Source')
	op = add(op, 'play', 'XSLT/Default mode')

	# This program copies a text node to the output
	prog = Program('DefaultText')
	root.add_sub(prog)
	op = add(prog.code.start, 'yank')
	op = add(op, 'mark_switch')
	op = add(op, 'put_as_child_end')
	op = add(op, 'move_left')
	op = add(op, 'mark_switch')
	
	# To start with, the cursor is on the source document node and
	# the mark is on the result document node.
	#
	# The mode program is called with:
	# => Cursor = context node
	#    Mark = result parent (append children here)
	# <= Cursor is undefined
	#    Mark is unchanged
	
	reader = StylesheetReader()
	sheet = reader.fromDocument(doc)

	global s
	s = sheet

	# sheet.matchTemplates is { mode -> { type -> { (ns, name) -> [match]     for elements
	#                         		      { 	      [match]     otherwise
	#
	# Each match is ((precedence,?), pattern, axis_type, TemplateElement)
	#
	# The list of matches is sorted; use the first that matches. Multiple lookups
	# may be required (eg, lookup 'html' then None (for 'node()' and '*')).
	# Patterns like 'text()|comment()' are broken down into two match elements.

	# XXX: Could have two modes with the same name but different namespaces...

	i = 1

	for mode in sheet.matchTemplates.keys():
		mode_name = mode_prog_name(mode)
		prog = Program(mode_name)
		root.add_sub(prog)
		tests = prog.code.start
		print "Mode", mode
		types = sheet.matchTemplates[mode]

		#loose_ends = []
		all = []
		for type in types.keys():
			if type == Node.ELEMENT_NODE:
				templates = types[type].values()[:]
			else:
				templates = [types[type]]

			# templates is a list of templates for items of this type when in this mode

			for tl in templates:
				for t in tl:
					all.append(t)

		all = all[:]
		all.sort()
		all.reverse() # highest numbers first
		
		last = None
		for sort_key, (unused_pattern, axis_type, template) in all:
			pattern = `template._match`

			if pattern == last:
				continue
			last = pattern

			#print sort_key, pattern, axis_type, template
			name = pattern.replace('/', '%')
			temp = Program(`i` + '-' + name)
			op = add(temp.code.start, 'mark_switch')
			make_template(op, template)
			i += 1
			prog.add_sub(temp)
			
			if pattern.startswith('/'):
				if pattern == '/':
					pattern = ''
				pattern = '/xslt/Source' + pattern # XXX: Hack
			tests = add(tests, 'xslt_fail_if', pattern)
			op = Op(action = ['play', temp.get_path()])
			tests.link_to(op, 'fail')
			add(op, 'mark_switch')
			#loose_ends.append(op)
		# Now add the built-in rules

		#print "Tidy", loose_ends

		tests = add(tests, 'xslt_fail_if', 'text()')
		op = Op(action = ['play', 'XSLT/DefaultText'])
		tests.link_to(op, 'fail')

		tests = add(tests, 'do_global', '*')
		tests = add(tests, 'map', prog.get_path())
		#tests = add(tests, 'mark_switch')
		#tests = add(tests, 'mark_switch')
		#[ op.link_to(tests, 'next') for op in loose_ends ]

	root.modified = 0
	return root