def test_minimal_template(self): template_info = Template(os.path.join(TEST_DATA, 'minimal')) node = template_info.xml_node() self.assertEqual(etree.tostring(node), ( b'<templateinfo><header/><body>' b'<js src="js/impress.js"/><js src="js/hovercraft-minimal.js"/>' b'</body></templateinfo>'))
def test_maximal_template(self): template_info = Template(os.path.join(TEST_DATA, 'maximal')) node = template_info.xml_node() self.assertEqual(etree.tostring(node), ( b'<templateinfo><header>' b'<css href="css/style.css" media="all"/>' b'<css href="css/print.css" media="print"/>' b'<css href="css/impressConsole.css" media="screen,projection"/>' b'<js src="js/dummy.js"/></header>' b'<body><js src="js/impress.js"/><js src="js/impressConsole.js"/>' b'<js src="js/hovercraft.js"/>' b'</body></templateinfo>'))
def test_template_maximal(self): template_info = Template(os.path.join(TEST_DATA, 'maximal')) with open(os.path.join(TEST_DATA, 'maximal', 'template.xsl'), 'rb') as xslfile: xsl = xslfile.read() self.assertEqual(template_info.xsl, xsl) template_files = [each.filepath for each in template_info.resources] self.assertIn('images/python-logo-master-v3-TM.png', template_files) self.assertIn('js/impress.js', template_files) self.assertIn('js/impressConsole.js', template_files) self.assertIn('js/hovercraft.js', template_files) js_bodies = [each.filepath for each in template_info.resources if each.resource_type == JS_RESOURCE and each.extra_info == JS_POSIION_BODY] self.assertIn('js/impress.js', js_bodies) self.assertIn('js/impressConsole.js', js_bodies) self.assertIn('js/hovercraft.js', js_bodies) js_headers = [each.filepath for each in template_info.resources if each.resource_type == JS_RESOURCE and each.extra_info == JS_POSIION_HEADER] self.assertIn('js/dummy.js', js_headers) self.assertEqual(template_info.resources[0].filepath, 'css/style.css') self.assertEqual(template_info.resources[0].extra_info, 'all') self.assertEqual(template_info.resources[1].filepath, 'css/print.css') self.assertEqual(template_info.resources[1].extra_info, 'print') self.assertEqual(template_info.resources[2].filepath, 'css/impressConsole.css') self.assertEqual(template_info.resources[2].extra_info, 'screen,projection') self.assertEqual(template_info.doctype, b'<!DOCTYPE html SYSTEM "about:legacy-compat">')
def test_skip_presenter_notes(self): template = Template(os.path.join(TEST_DATA, 'maximal')) html = rst2html(os.path.join(TEST_DATA, 'presenter-notes.rst'), template, skip_notes=True) target = ( b'<!DOCTYPE html SYSTEM "about:legacy-compat"><html ' b'xmlns="http://www.w3.org/1999/xhtml"><head><title>Document ' b'title</title><link rel="stylesheet" href="css/style.css" ' b'media="all"></link><link rel="stylesheet" ' b'href="css/print.css" media="print"></link><link rel="stylesheet" ' b'href="css/impressConsole.css" ' b'media="screen,projection"></link><script type="text/javascript" ' b'src="js/dummy.js"></script></head><body ' b'class="impress-not-supported"><div id="impress">' b'<div class="step" step="0" data-x="0" ' b'data-y="0"><h1 id="hovercrafts-presenter-notes">Hovercrafts presenter ' b'notes</h1><p>Hovercraft! supports presenter notes. It does this by ' b'taking anything in a\nwhat is calles a "notes-admonition" and making ' b'that into presenter notes.</p></div><div ' b'class="step" step="1" data-x="1600" data-y="0"><img ' b'src="images/python-logo-master-v3-TM.png" alt="" width="" height="">' b'</img></div></div><div id="hovercraft-help" class="show"><table><tr>' b'<th>Left, Down, Page Down, Space</th><td>Next slide</td></tr><tr>' b'<th>Right, Up, Page Up</th><td>Previous slide</td></tr><tr><th>H</th>' b'<td>Toggle this help</td></tr></table></div><script type="text/javascript" ' b'src="js/impress.js"></script><script type="text/javascript" ' b'src="js/impressConsole.js"></script><script type="text/javascript" ' b'src="js/hovercraft.js"></script></body></html>') self.assertEqual(html, target)
def test_template_minimal(self): template_info = Template(os.path.join(TEST_DATA, 'minimal')) with open(os.path.join(TEST_DATA, 'minimal', 'template.xsl'), 'rb') as xslfile: xsl = xslfile.read() self.assertEqual(template_info.xsl, xsl) template_files = [each.filepath for each in template_info.resources] self.assertIn('js/impress.js', template_files) self.assertIn('js/hovercraft-minimal.js', template_files) css_files = list(each.filepath for each in template_info.resources if each.resource_type == CSS_RESOURCE) self.assertEqual(len(css_files), 0) self.assertEqual(template_info.doctype, b'<!DOCTYPE html>')
def test_slide_with_class(self): template = Template(os.path.join(TEST_DATA, 'minimal')) html = rst2html(os.path.join(TEST_DATA, 'slide_class.rst'), template) target = ( b'<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml">' b'<body><div id="impress">' b'<div class="step something-else" step="0" data-x="0" data-y="0">' b'<p>This is some text</p></div></div>' b'<script type="text/javascript" src="js/impress.js"></script>' b'<script type="text/javascript" src="js/hovercraft-minimal.js">' b'</script></body></html>') self.assertEqual(html, target)
def test_template_paths(self): # You can specify a folder or a cfg file and that's the same thing. template_info1 = Template(os.path.join(TEST_DATA, 'minimal')) template_info2 = Template( os.path.join(TEST_DATA, 'minimal', 'template.cfg')) self.assertEqual(etree.tostring(template_info1.xml_node()), etree.tostring(template_info2.xml_node()))
def test_small(self): template = Template(os.path.join(TEST_DATA, 'minimal')) html = rst2html(os.path.join(TEST_DATA, 'simple.rst'), template) target = ( b'<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml">' b'<body><div id="impress">' b'<div class="step" step="0" data-x="0" data-y="0">' b'<h1 id="simple-presentation">Simple Presentation</h1>' b'<p>This presentation has two slides, each with a header and ' b'some text.</p></div><div class="step" step="1" data-x="1600" ' b'data-y="0"><h1 id="second-slide">Second slide</h1>' b'<p>There is no positioning or anything fancy.</p></div></div>' b'<script type="text/javascript" src="js/impress.js"></script>' b'<script type="text/javascript" src="js/hovercraft-minimal.js">' b'</script></body></html>') self.assertEqual(html, target)
def test_big(self): template = Template(os.path.join(TEST_DATA, 'maximal')) html = rst2html(os.path.join(TEST_DATA, 'advanced.rst'), template) target = ( b'<!DOCTYPE html SYSTEM "about:legacy-compat">' b'<html xmlns="http://www.w3.org/1999/xhtml"><head><title>' b'Presentation title</title><link rel="stylesheet" ' b'href="css/style.css" media="all"></link>' b'<link rel="stylesheet" href="css/print.css" media="print">' b'</link><link rel="stylesheet" href="css/impressConsole.css" ' b'media="screen,projection"></link><link rel="stylesheet" href="extra.css" ' b'media="screen"></link><script type="text/javascript" ' b'src="js/dummy.js"></script></head><body ' b'class="impress-not-supported"><div id="impress" ' b'data-transition-duration="2000" auto-console="True"><div class="step" step="0" data-x="1000" ' b'data-y="1600"><h1 id="advanced-presentation">Advanced Presentation' b'</h1><p>Here we show the positioning feature, where we can ' b'explicitly set a position\non one of the steps.</p></div><div ' b'class="step" step="1" id="name-this-step" data-x="2600" data-y="1600"><h1 ' b'id="formatting">Formatting</h1><p>Let us also try some basic ' b'formatting, like <em>italic</em>, and <strong>bold</strong>.</p>' b'<ul><li>We can also</li><li>have a list</li><li>of things.</li>' b'</ul></div><div class="step" step="2" data-x="4200" data-y="1600">' b'<p>There should also be possible to have\npreformatted text for ' b'code.</p><pre class="highlight code python"><span class="k">def' b'</span> <span class="nf">foo</span><span class="p">(</span><span ' b'class="n">bar</span><span class="p">):</span>\n <span class="c">' b'# Comment</span>\n <span class="n">a</span> <span class="o">=' b'</span> <span class="mi">1</span> <span class="o">+</span> <span ' b'class="s">"hubbub"</span>\n <span class="k">return</span> ' b'<span class="bp">None</span></pre></div><div class="step" ' b'step="3" data-x="5800" data-y="1600"><img ' b'src="images/python-logo-master-v3-TM.png" alt="" width="" ' b'height=""></img></div><div class="step" step="4" data-x="7400" ' b'data-y="1600"><h1 id="character-sets">Character sets</h1>' b'<p>The character set is UTF-8 as of now. Like this: ' b'åäö.</p></div></div>' b'<div id="hovercraft-help" class="show"><table><tr>' b'<th>Left, Down, Page Down, Space</th><td>Next slide</td></tr><tr>' b'<th>Right, Up, Page Up</th><td>Previous slide</td></tr><tr><th>H</th>' b'<td>Toggle this help</td></tr></table></div><script type="text/javascript" ' b'src="js/impress.js"></script><script type="text/javascript" ' b'src="js/impressConsole.js"></script><script type="text/javascript" ' b'src="js/hovercraft.js"></script></body></html>') self.assertEqual(html, target)
def test_container_directive(self): template = Template(os.path.join(TEST_DATA, 'minimal')) html = rst2html(os.path.join(TEST_DATA, 'container.rst'), template) target = ( b'<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml">' b'<body><div id="impress">' b'<div class="step" step="0" data-x="0" data-y="0">' b'<div class="my-class">' b'<p>This is some text in the container</p>' b'</div>' b'<div id="my-thing">' b'<p>This should have an id</p>' b'</div>' b'</div></div>' b'<script type="text/javascript" src="js/impress.js"></script>' b'<script type="text/javascript" src="js/hovercraft-minimal.js">' b'</script></body></html>') self.assertEqual(html, target)
def test_template_maximal(self): template_info = Template(os.path.join(TEST_DATA, "maximal")) with open(os.path.join(TEST_DATA, "maximal", "template.xsl"), "rb") as xslfile: xsl = xslfile.read() self.assertEqual(template_info.xsl, xsl) template_files = [each.filepath for each in template_info.resources] self.assertIn("images/hovercraft_logo.png", template_files) self.assertIn("js/impress.js", template_files) self.assertIn("js/impressConsole.js", template_files) self.assertIn("js/hovercraft.js", template_files) js_bodies = [ each.filepath for each in template_info.resources if each.resource_type == JS_RESOURCE and each.extra_info == JS_POSITION_BODY ] self.assertIn("js/impress.js", js_bodies) self.assertIn("js/impressConsole.js", js_bodies) self.assertIn("js/hovercraft.js", js_bodies) js_headers = [ each.filepath for each in template_info.resources if each.resource_type == JS_RESOURCE and each.extra_info == JS_POSITION_HEADER ] self.assertIn("js/dummy.js", js_headers) self.assertEqual(template_info.resources[0].filepath, "css/style.css") self.assertEqual(template_info.resources[0].extra_info, "all") self.assertEqual(template_info.resources[1].filepath, "css/print.css") self.assertEqual(template_info.resources[1].extra_info, "print") self.assertEqual(template_info.resources[2].filepath, "css/impressConsole.css") self.assertEqual(template_info.resources[2].extra_info, "screen,projection") self.assertEqual(template_info.doctype, b'<!DOCTYPE html SYSTEM "about:legacy-compat">')
def test_presenter_notes(self): template = Template(os.path.join(TEST_DATA, 'maximal')) html = rst2html(os.path.join(TEST_DATA, 'presenter-notes.rst'), template) target = ( b'<!DOCTYPE html SYSTEM "about:legacy-compat"><html ' b'xmlns="http://www.w3.org/1999/xhtml"><head><title>Document ' b'title</title><link rel="stylesheet" href="css/style.css" ' b'media="all"></link><link rel="stylesheet" ' b'href="css/print.css" media="print"></link><link rel="stylesheet" ' b'href="css/impressConsole.css" ' b'media="screen,projection"></link><script type="text/javascript" ' b'src="js/dummy.js"></script></head><body ' b'class="impress-not-supported"><div id="impress">' b'<div class="step" step="0" data-x="0" ' b'data-y="0"><h1 id="hovercrafts-presenter-notes">Hovercrafts presenter ' b'notes</h1><p>Hovercraft! supports presenter notes. It does this by ' b'taking anything in a\nwhat is calles a "notes-admonition" and making ' b'that into presenter notes.</p><div class="notes"><p>Hence, this will ' b'show up as presenter notes.\nYou have still access to a lot of ' b'formatting, like</p><ul><li>Bullet lists</li><li>And <em>all</em> ' b'types of <strong>inline formatting</strong></li></ul></div></div><div ' b'class="step" step="1" data-x="1600" data-y="0"><img ' b'src="images/python-logo-master-v3-TM.png" alt="" width="" ' b'height=""></img><div class="notes"><p>You don\'t have to start the ' b'text on the same line as\nthe note, but you can.</p><p>You can also ' b'have several paragraphs. You can not have any\nheadings of any kind ' b'though.</p><p><strong>But you can fake them through ' b'bold-text</strong></p><p>And that\'s useful enough for presentation ' b'notes.</p></div></div></div>' b'<div id="hovercraft-help" class="show"><table><tr>' b'<th>Left, Down, Page Down, Space</th><td>Next slide</td></tr><tr>' b'<th>Right, Up, Page Up</th><td>Previous slide</td></tr><tr><th>H</th>' b'<td>Toggle this help</td></tr></table></div><script type="text/javascript" ' b'src="js/impress.js"></script><script type="text/javascript" ' b'src="js/impressConsole.js"></script><script type="text/javascript" ' b'src="js/hovercraft.js"></script></body></html>') self.assertEqual(html, target)
def test_tables(self): template = Template(os.path.join(TEST_DATA, 'minimal')) html = rst2html(os.path.join(TEST_DATA, 'table.rst'), template) target = ( b'<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml">' b'<body><div id="impress">' b'<div class="step" step="0" data-x="0" data-y="0">' b'<table cellpadding="0" cellspacing="0" class="my-table-class">' b'Truth table for "not"' b'<thead><tr><th><p>Name</p></th><th><p>Money Owed</p></th></tr>' b'</thead><tbody>' b'<tr><td><p>Adam Alpha</p></td><td><p>100</p></td></tr>' b'</tbody></table>' b'<table cellpadding="0" cellspacing="0" id="my-table">' b'<thead><tr><th><p>Number</p></th><th><p>Two</p></th></tr>' b'</thead><tbody>' b'<tr><td><p>Adam Alpha</p></td><td><p>100</p></td></tr>' b'</tbody></table>' b'</div></div>' b'<script type="text/javascript" src="js/impress.js"></script>' b'<script type="text/javascript" src="js/hovercraft-minimal.js">' b'</script></body></html>') self.assertEqual(html, target)
def test_container_directive(self): template = Template(os.path.join(TEST_DATA, 'minimal')) html = rst2html(os.path.join(TEST_DATA, 'container.rst'), template) self.assertEqual(html, HTML_OUTPUTS['container_directive'])
def test_table(self): template = Template(os.path.join(TEST_DATA, 'minimal')) html = rst2html(os.path.join(TEST_DATA, 'table.rst'), template) self.assertEqual(html, HTML_OUTPUTS['table'])
def test_slide_with_class(self): template = Template(os.path.join(TEST_DATA, 'minimal')) html = rst2html(os.path.join(TEST_DATA, 'slide_class.rst'), template) self.assertEqual(html, HTML_OUTPUTS['slide_with_class'])
def test_comments(self): template = Template(os.path.join(TEST_DATA, 'minimal')) html = rst2html(os.path.join(TEST_DATA, 'comment.rst'), template) self.assertEqual(html, HTML_OUTPUTS['comment'])
def test_skip_presenter_notes(self): template = Template(os.path.join(TEST_DATA, 'maximal')) html = rst2html(os.path.join(TEST_DATA, 'presenter-notes.rst'), template, skip_notes=True) self.assertEqual(html, HTML_OUTPUTS['skip-presenter-notes'])
def test_container_directive(self): template = Template(os.path.join(TEST_DATA, "minimal")) html, deps = rst2html(os.path.join(TEST_DATA, "container.rst"), template) self.assertEqual(html, HTML_OUTPUTS["container_directive"])
def test_big(self): template = Template(os.path.join(TEST_DATA, "maximal")) html, deps = rst2html(os.path.join(TEST_DATA, "advanced.rst"), template) self.assertEqual(html, HTML_OUTPUTS["advanced"])
def test_small(self): template = Template(os.path.join(TEST_DATA, 'minimal')) html, deps = rst2html(os.path.join(TEST_DATA, 'simple.rst'), template) self.assertEqual(html, HTML_OUTPUTS['simple'])
def test_comments(self): template = Template(os.path.join(TEST_DATA, "minimal")) html, deps = rst2html(os.path.join(TEST_DATA, "comment.rst"), template) self.assertEqual(html, HTML_OUTPUTS["comment"])
def test_slide_with_class(self): template = Template(os.path.join(TEST_DATA, "minimal")) html, deps = rst2html(os.path.join(TEST_DATA, "slide_class.rst"), template) self.assertEqual(html, HTML_OUTPUTS["slide_with_class"])
def test_table(self): template = Template(os.path.join(TEST_DATA, "minimal")) html, deps = rst2html(os.path.join(TEST_DATA, "table.rst"), template) self.assertEqual(html, HTML_OUTPUTS["table"])
def test_template_paths(self): # You can specify a folder or a cfg file and that's the same thing. template_info1 = Template(os.path.join(TEST_DATA, 'minimal')) template_info2 = Template(os.path.join(TEST_DATA, 'minimal', 'template.cfg')) self.assertEqual(etree.tostring(template_info1.xml_node()), etree.tostring(template_info2.xml_node()))
def test_include(self): template = Template(os.path.join(TEST_DATA, 'minimal')) html, deps = rst2html(os.path.join(TEST_DATA, 'include.rst'), template) self.assertIn(b'Presentation with an include</h1>', html) # Make sure the simple presentation was included: self.assertIn(b'Simple Presentation</h1>', html)
def test_skip_presenter_notes(self): template = Template(os.path.join(TEST_DATA, "maximal")) html, deps = rst2html(os.path.join(TEST_DATA, "presenter-notes.rst"), template, skip_notes=True) self.assertEqual(html, HTML_OUTPUTS["skip-presenter-notes"])
def test_big(self): template = Template(os.path.join(TEST_DATA, 'maximal')) html = rst2html(os.path.join(TEST_DATA, 'advanced.rst'), template) self.assertEqual(html, HTML_OUTPUTS['advanced'])
def main(): # That the argparse default strings are lowercase is ugly. import gettext def my_gettext(s): return s.capitalize() gettext.gettext = my_gettext import os import re import argparse from lxml import html from hovercraft.generate import rst2html, copy_resource from hovercraft.template import Template, CSS_RESOURCE parser = argparse.ArgumentParser( description='Create impress.js presentations with reStructuredText', add_help=False) parser.add_argument( 'presentation', metavar='<presentation>', help='The path to the reStructuredText presentation file.') parser.add_argument( 'targetdir', metavar='<targetdir>', help=('The directory where the presentation is written. ' 'Will be created if it does not exist.')) parser.add_argument('-h', '--help', action='help', help='Show this help.') parser.add_argument( '-t', '--template', help=( 'Specify a template. Must be a .cfg file, or a directory with a ' 'template.cfg file. If not given it will use a default template.')) parser.add_argument( '-c', '--css', help='An additional css file for the presentation to use.') parser.add_argument( '-a', '--auto-console', action='store_true', help=('Pop up the console automatically. This is useful when you are ' 'rehearsing and making sure the presenter notes are correct.')) parser.add_argument('-s', '--skip-help', action='store_true', help=('Do not show the initial help popup.')) parser.add_argument('-n', '--skip-notes', action='store_true', help=('Do not include presenter notes in the output.')) args = parser.parse_args() # Parse the template info template_info = Template(args.template) if args.css: presentation_dir = os.path.split(args.presentation)[0] target_path = os.path.relpath(args.css, presentation_dir) template_info.add_resource(args.css, CSS_RESOURCE, target=target_path, extra_info='all') # Make the resulting HTML htmldata = rst2html(args.presentation, template_info, args.auto_console, args.skip_help, args.skip_notes) # Write the HTML out if not os.path.exists(args.targetdir): os.makedirs(args.targetdir) with open(os.path.join(args.targetdir, 'index.html'), 'wb') as outfile: outfile.write(htmldata) # Copy supporting files template_info.copy_resources(args.targetdir) # Copy images from the source: sourcedir = os.path.split(os.path.abspath(args.presentation))[0] tree = html.fromstring(htmldata) for image in tree.iterdescendants('img'): filename = image.attrib['src'] copy_resource(filename, sourcedir, args.targetdir) RE_CSS_URL = re.compile(br"""url\(['"]?(.*?)['"]?[\)\?\#]""") # Copy any files referenced by url() in the css-files: for resource in template_info.resources: if resource.resource_type != CSS_RESOURCE: continue # path in CSS is relative to CSS file; construct source/dest accordingly css_base = template_info.template if resource.is_in_template else sourcedir css_sourcedir = os.path.dirname( os.path.join(css_base, resource.filepath)) css_targetdir = os.path.dirname( os.path.join(args.targetdir, resource.final_path())) uris = RE_CSS_URL.findall(template_info.read_data(resource)) uris = [uri.decode() for uri in uris] for filename in uris: copy_resource(filename, css_sourcedir, css_targetdir)
def main(): # That the argparse default strings are lowercase is ugly. import gettext def my_gettext(s): return s.capitalize() gettext.gettext = my_gettext import os import re import argparse from lxml import html from hovercraft.generate import rst2html, copy_resource from hovercraft.template import Template, CSS_RESOURCE parser = argparse.ArgumentParser( description='Create impress.js presentations with reStructuredText', add_help=False) parser.add_argument( 'presentation', metavar='<presentation>', help='The path to the reStructuredText presentation file.') parser.add_argument( 'targetdir', metavar='<targetdir>', help=('The directory where the presentation is written. ' 'Will be created if it does not exist.')) parser.add_argument( '-h', '--help', action='help', help='Show this help.') parser.add_argument( '-t', '--template', help=('Specify a template. Must be a .cfg file, or a directory with a ' 'template.cfg file. If not given it will use a default template.')) parser.add_argument( '-c', '--css', help='An additional css file for the presentation to use.') parser.add_argument( '-a', '--auto-console', action='store_true', help=('Pop up the console automatically. This is useful when you are ' 'rehearsing and making sure the presenter notes are correct.')) parser.add_argument( '-s', '--skip-help', action='store_true', help=('Do not show the initial help popup.')) parser.add_argument( '-n', '--skip-notes', action='store_true', help=('Do not include presenter notes in the output.')) args = parser.parse_args() # Parse the template info template_info = Template(args.template) if args.css: presentation_dir = os.path.split(args.presentation)[0] target_path = os.path.relpath(args.css, presentation_dir) template_info.add_resource(args.css, CSS_RESOURCE, target=target_path, extra_info='all') # Make the resulting HTML htmldata = rst2html(args.presentation, template_info, args.auto_console, args.skip_help, args.skip_notes) # Write the HTML out if not os.path.exists(args.targetdir): os.makedirs(args.targetdir) with open(os.path.join(args.targetdir, 'index.html'), 'wb') as outfile: outfile.write(htmldata) # Copy supporting files template_info.copy_resources(args.targetdir) # Copy images from the source: sourcedir = os.path.split(os.path.abspath(args.presentation))[0] tree = html.fromstring(htmldata) for image in tree.iterdescendants('img'): filename = image.attrib['src'] copy_resource(filename, sourcedir, args.targetdir) RE_CSS_URL = re.compile(br"""url\(['"]?(.*?)['"]?[\)\?\#]""") # Copy any files referenced by url() in the css-files: for resource in template_info.resources: if resource.resource_type != CSS_RESOURCE: continue # path in CSS is relative to CSS file; construct source/dest accordingly css_base = template_info.template if resource.is_in_template else sourcedir css_sourcedir = os.path.dirname(os.path.join(css_base, resource.filepath)) css_targetdir = os.path.dirname(os.path.join(args.targetdir, resource.final_path())) uris = RE_CSS_URL.findall(template_info.read_data(resource)) uris = [uri.decode() for uri in uris] for filename in uris: copy_resource(filename, css_sourcedir, css_targetdir)