예제 #1
0
파일: hooks.py 프로젝트: edavis/wok
    def __call__(self, page):
        if not etree:
            return
        logging.debug('Called hook HeadingAnchors on {0}'.format(page))
        parser = etree.HTMLParser()
        sio_source = StringIO(page.rendered)
        tree = etree.parse(sio_source, parser)

        for lvl in range(1, self.max_heading+1):
            headings = tree.iterfind('//h{0}'.format(lvl))
            for heading in headings:
                if not heading.text:
                    continue
                logging.debug('[HeadingAnchors] {0} {1}'
                        .format(heading, heading.text))

                name = 'heading-{0}'.format(slugify(heading.text))
                anchor = etree.Element('a')
                anchor.set('class', 'heading_anchor')
                anchor.set('href', '#' + name)
                anchor.set('title', 'Permalink to this section.')
                anchor.text = u'¶'
                heading.append(anchor)

                heading.set('id', name)

        sio_destination = StringIO()
        tree.write(sio_destination)
        page.rendered = sio_destination.getvalue()
예제 #2
0
파일: hooks.py 프로젝트: robatron/wok
    def __call__(self, page):
        if not etree:
            return
        logging.debug('Called hook HeadingAnchors on {0}'.format(page))
        parser = etree.HTMLParser()
        sio_source = StringIO(page.rendered)
        tree = etree.parse(sio_source, parser)

        for lvl in range(1, self.max_heading + 1):
            headings = tree.iterfind('//h{0}'.format(lvl))
            for heading in headings:
                if not heading.text:
                    continue
                logging.debug('[HeadingAnchors] {0} {1}'.format(
                    heading, heading.text))

                name = 'heading-{0}'.format(slugify(heading.text))
                anchor = etree.Element('a')
                anchor.set('class', 'heading_anchor')
                anchor.set('href', '#' + name)
                anchor.set('title', 'Permalink to this section.')
                anchor.text = u'¶'
                heading.append(anchor)

                heading.set('id', name)

        sio_destination = StringIO()
        tree.write(sio_destination)
        page.rendered = sio_destination.getvalue()
예제 #3
0
    def __call__(self, page):
        if not etree:
            return
        logging.debug('Called hook HeadingAnchors on {0}'.format(page))
        parser = etree.HTMLParser()
        sio_source = StringIO(page.rendered)
        tree = etree.parse(sio_source, parser)

        for lvl in range(1, self.max_heading + 1):
            headings = tree.iterfind('//h{0}'.format(lvl))
            for heading in headings:
                if not heading.text:
                    continue
                logging.debug('[HeadingAnchors] {0} {1}'.format(
                    heading, heading.text))

                name = 'heading-{0}'.format(slugify(heading.text))
                anchor = etree.Element('a')
                anchor.set('class', 'heading_anchor')
                anchor.set('href', '#' + name)
                anchor.set('title', 'Permalink to this section.')
                anchor.text = u'¶'
                heading.append(anchor)

                heading.set('id', name)

        sio_destination = StringIO()

        # Use the extension of the template to determine the type of document
        if page.template.filename.endswith(".html") or page.filename.endswith(
                ".htm"):
            logging.debug(
                '[HeadingAnchors] outputting {0} as HTML'.format(page))
            tree.write(sio_destination, method='html')
        else:
            logging.debug(
                '[HeadingAnchors] outputting {0} as XML'.format(page))
            tree.write(sio_destination)
        page.rendered = sio_destination.getvalue()
예제 #4
0
파일: hooks.py 프로젝트: jgoodson/wok
    def __call__(self, config, page):
        if not etree:
            return
        logging.debug('Called hook HeadingAnchors on {0}'.format(page))
        parser = etree.HTMLParser()
        sio_source = StringIO(page.rendered)
        tree = etree.parse(sio_source, parser)

        for lvl in range(1, self.max_heading+1):
            headings = tree.iterfind('//h{0}'.format(lvl))
            for heading in headings:
                if not heading.text:
                    continue
                logging.debug('[HeadingAnchors] {0} {1}'
                        .format(heading, heading.text))

                name = 'heading-{0}'.format(slugify(heading.text))
                anchor = etree.Element('a')
                anchor.set('class', 'heading_anchor')
                anchor.set('href', '#' + name)
                anchor.set('title', 'Permalink to this section.')
                anchor.text = u'¶'
                heading.append(anchor)

                heading.set('id', name)

        sio_destination = StringIO()

	# Use the extension of the template to determine the type of document 
	if page.template.filename.endswith(".html") or page.filename.endswith(".htm"):
        	logging.debug('[HeadingAnchors] outputting {0} as HTML'.format(page))
	        tree.write(sio_destination, method='html')
	else:
        	logging.debug('[HeadingAnchors] outputting {0} as XML'.format(page))
	        tree.write(sio_destination)
        page.rendered = sio_destination.getvalue()
예제 #5
0
파일: page.py 프로젝트: naringas/wok
    def build_meta(self):
        """
        Ensures the guarantees about metadata for documents are valid.

        `page.title` - Will be a string.
        `page.slug` - Will be a string.
        `page.author` - Will have fields `name` and `email`.
        `page.authors` - Will be a list of Authors.
        `page.category` - Will be a list.
        `page.published` - Will exist.
        `page.datetime` - Will be a datetime, or None.
        `page.date` - Will be a date, or None.
        `page.time` - Will be a time, or None.
        `page.tags` - Will be a list.
        `page.url` - Will be the url of the page, relative to the web root.
        `page.subpages` - Will be a list containing every sub page of this page
        """

        self.engine.run_hook('page.meta.pre', self)

        if not self.meta:
            self.meta = {}

        # title
        if not 'title' in self.meta:
            if self.filename:
                # Take off the last file extension.
                self.meta['title'] = '.'.join(self.filename.split('.')[:-1])
                if (self.meta['title'] == ''):
                    self.meta['title'] = self.filename

                logging.warning("You didn't specify a title in {0}. Using the "
                                "file name as a title.".format(self.path))
            elif 'slug' in self.meta:
                self.meta['title'] = self.meta['slug']
                logging.warning("You didn't specify a title in {0}, which was "
                        "not generated from a file. Using the slug as a title."
                        .format(self.meta['slug']))
            else:
                logging.error("A page was generated that is not from a file, "
                        "has no title, and no slug. I don't know what to do. "
                        "Not using this page.")
                logging.info("Bad Meta's keys: {0}".format(self.meta.keys()))
                logging.debug("Bad Meta: {0}".format(self.meta))
                raise BadMetaException()

        # slug
        if not 'slug' in self.meta:
            if self.filename:
                filename_no_ext = '.'.join(self.filename.split('.')[:-1])
                if filename_no_ext == '':
                    filename_no_ext = self.filename
                self.meta['slug'] = util.slugify(filename_no_ext)
                logging.info("You didn't specify a slug, generating it from the "
                             "filename.")
            else:
                self.meta['slug'] = util.slugify(self.meta['title'])
                logging.info("You didn't specify a slug, and no filename "
                             "exists. Generating the slug from the title.")

        elif self.meta['slug'] != util.slugify(self.meta['slug']):
            logging.warning('Your slug should probably be all lower case, and '
                            'match "[a-z0-9-]*"')

        # authors and author
        authors = self.meta.get('authors', self.meta.get('author', None))
        if isinstance(authors, list):
            self.meta['authors'] = [Author.parse(a) for a in authors]
        elif isinstance(authors, str):
            self.meta['authors'] = [Author.parse(a) for a in authors.split(',')]
            if len(self.meta['authors']) > 1:
                logging.warn('Deprecation Warning: Use YAML lists instead of '
                        'CSV for multiple authors. i.e. ["John Doe", "Jane '
                        'Smith"] instead of "John Doe, Jane Smith". In '
                        '{0}.'.format(self.path))

        elif authors is None:
            self.meta['authors'] = self.options.get('authors', [])
        else:
            # wait, what? Authors is of wrong type.
            self.meta['authors'] = []
            logging.error(('Authors in {0} is an unknown type. Valid types '
                           'are string or list. Instead it is a {1}')
                           .format(self.meta['slug']), authors.type)

        if self.meta['authors']:
            self.meta['author'] = self.meta['authors'][0]
        else:
            self.meta['author'] = Author()

        # category
        if 'category' in self.meta:
            if isinstance(self.meta['category'], str):
                self.meta['category'] = self.meta['category'].split('/')
            elif isinstance(self.meta['category'], list):
                pass
            else:
                # category is of wrong type.
                logging.error('Category in {0} is an unknown type. Valid '
                              'types are string or list. Instead it is a {1}'
                              .format(self.meta['slug'], type(self.meta['category'])))
                self.meta['category'] = []
        else:
            self.meta['category'] = []
        if self.meta['category'] == None:
            self.meta = []

        # published
        if not 'published' in self.meta:
            self.meta['published'] = True

        # make_file
        if not 'make_file' in self.meta:
            self.meta['make_file'] = True

        # datetime, date, time
        util.date_and_times(self.meta)

        # tags
        if 'tags' in self.meta:
            if isinstance(self.meta['tags'], list):
                # good
                pass
            elif isinstance(self.meta['tags'], str):
                self.meta['tags'] = [t.strip() for t in
                    self.meta['tags'].split(',')]
                if len(self.meta['tags']) > 1:
                    logging.warn('Deprecation Warning: Use YAML lists instead '
                            'of CSV for multiple tags. i.e. tags: [guide, '
                            'howto] instead of tags: guide, howto. In {0}.'
                            .format(self.path))
        else:
            self.meta['tags'] = []

        logging.debug('Tags for {0}: {1}'.
                format(self.meta['slug'], self.meta['tags']))

        # pagination
        if 'pagination' not in self.meta:
            self.meta['pagination'] = {}

        if 'cur_page' not in self.meta['pagination']:
            self.meta['pagination']['cur_page'] = 1
        if 'num_pages' not in self.meta['pagination']:
            self.meta['pagination']['num_pages'] = 1

        # template
        try:
            template_type = str(self.meta.get('type', 'default'))
            self.template = self.tmpl_env.get_template(template_type + '.*')
        except jinja2.loaders.TemplateNotFound:
            logging.error('No template "{0}.*" found in template directory. Aborting.'
                    .format(template_type))
            sys.exit()
        except AmbiguousTemplate:
            logging.error(('Ambiguous template found. There are two files that '
                          'match "{0}.*". Aborting.').format(template_type))
            sys.exit()

        # url
        parts = {
            'slug': self.meta['slug'],
            'category': '/'.join(self.meta['category']),
            'page': self.meta['pagination']['cur_page'],
            'date': self.meta['date'],
            'datetime': self.meta['datetime'],
            'time': self.meta['time'],
        }
        logging.debug('current page: ' + repr(parts['page']))

        # Pull extensions from the template's real file name.
        parts['ext'] = os.path.splitext(self.template.filename)[1]
        if parts['ext']:
            parts['ext'] = parts['ext'][1:] # remove leading dot
        # Deprecated
        parts['type'] = parts['ext']
        self.meta['ext'] = parts['ext']

        if parts['page'] == 1:
            parts['page'] = ''

        if 'url' in self.meta:
            logging.debug('Using page url pattern')
            self.url_pattern = self.meta['url']
        else:
            logging.debug('Using global url pattern')
            self.url_pattern = self.options['url_pattern']

        self.meta['url'] = self.url_pattern.format(**parts)

        logging.info('URL pattern is: {0}'.format(self.url_pattern))
        logging.info('URL parts are: {0}'.format(parts))

        # Get rid of extra slashes
        self.meta['url'] = re.sub(r'//+', '/', self.meta['url'])

        # If we have been asked to, rip out any plain "index.html"s
        if not self.options['url_include_index']:
            self.meta['url'] = re.sub(r'/index\.html$', '/', self.meta['url'])

        # Some urls should start with /, some should not.
        if self.options['relative_urls'] and self.meta['url'][0] == '/':
            self.meta['url'] = self.meta['url'][1:]
        if not self.options['relative_urls'] and self.meta['url'][0] != '/':
            self.meta['url'] = '/' + self.meta['url']

        logging.debug('url is: ' + self.meta['url'])

        # subpages
        self.meta['subpages'] = []

        self.engine.run_hook('page.meta.post', self)
예제 #6
0
    def build_meta(self):
        """
        Ensures the guarantees about metadata for documents are valid.

        `page.title` - Will be a string.
        `page.slug` - Will be a string.
        `page.author` - Will have fields `name` and `email`.
        `page.authors` - Will be a list of Authors.
        `page.category` - Will be a list.
        `page.published` - Will exist.
        `page.datetime` - Will be a datetime, or None.
        `page.date` - Will be a date, or None.
        `page.time` - Will be a time, or None.
        `page.tags` - Will be a list.
        `page.url` - Will be the url of the page, relative to the web root.
        `page.subpages` - Will be a list containing every sub page of this page
        """

        self.engine.run_hook('page.meta.pre', self)

        if not self.meta:
            self.meta = {}

        # title
        if not 'title' in self.meta:
            if self.filename:
                # Take off the last file extension.
                self.meta['title'] = '.'.join(self.filename.split('.')[:-1])
                if (self.meta['title'] == ''):
                    self.meta['title'] = self.filename

                logging.warning("You didn't specify a title in {0}. Using the "
                                "file name as a title.".format(self.path))
            elif 'slug' in self.meta:
                self.meta['title'] = self.meta['slug']
                logging.warning(
                    "You didn't specify a title in {0}, which was "
                    "not generated from a file. Using the slug as a title.".
                    format(self.meta['slug']))
            else:
                logging.error(
                    "A page was generated that is not from a file, "
                    "has no title, and no slug. I don't know what to do. "
                    "Not using this page.")
                logging.info("Bad Meta's keys: {0}".format(self.meta.keys()))
                logging.debug("Bad Meta: {0}".format(self.meta))
                raise BadMetaException()

        # slug
        if not 'slug' in self.meta:
            if self.filename:
                filename_no_ext = '.'.join(self.filename.split('.')[:-1])
                self.meta['slug'] = util.slugify(filename_no_ext)
                logging.info(
                    "You didn't specify a slug, generating it from the "
                    "filename.")
            else:
                self.meta['slug'] = util.slugify(self.meta['title'])
                logging.info("You didn't specify a slug, and no filename "
                             "exists. Generating the slug from the title.")

        elif self.meta['slug'] != util.slugify(self.meta['slug']):
            logging.warning('Your slug should probably be all lower case, and '
                            'match "[a-z0-9-]*"')

        # authors and author
        authors = self.meta.get('authors', self.meta.get('author', None))
        if isinstance(authors, list):
            self.meta['authors'] = [Author.parse(a) for a in authors]
        elif isinstance(authors, str):
            self.meta['authors'] = [
                Author.parse(a) for a in authors.split(',')
            ]
            if len(self.meta['authors']) > 1:
                logging.warn(
                    'Deprecation Warning: Use YAML lists instead of '
                    'CSV for multiple authors. i.e. ["John Doe", "Jane '
                    'Smith"] instead of "John Doe, Jane Smith". In '
                    '{0}.'.format(self.path))

        elif authors is None:
            self.meta['authors'] = self.options.get('authors', [])
        else:
            # wait, what? Authors is of wrong type.
            self.meta['authors'] = []
            logging.error(('Authors in {0} is an unknown type. Valid types '
                           'are string or list. Instead it is a {1}').format(
                               self.meta['slug']), authors.type)

        if self.meta['authors']:
            self.meta['author'] = self.meta['authors'][0]
        else:
            self.meta['author'] = Author()

        # category
        if 'category' in self.meta:
            if isinstance(self.meta['category'], str):
                self.meta['category'] = self.meta['category'].split('/')
            elif isinstance(self.meta['category'], list):
                pass
            else:
                # category is of wrong type.
                logging.error(
                    'Category in {0} is an unknown type. Valid '
                    'types are string or list. Instead it is a {1}'.format(
                        self.meta['slug'], type(self.meta['category'])))
                self.meta['category'] = []
        else:
            self.meta['category'] = []
        if self.meta['category'] == None:
            self.meta = []

        # published
        if not 'published' in self.meta:
            self.meta['published'] = True

        # make_file
        if not 'make_file' in self.meta:
            self.meta['make_file'] = True

        # datetime, date, time
        util.date_and_times(self.meta)

        # tags
        if 'tags' in self.meta:
            if isinstance(self.meta['tags'], list):
                # good
                pass
            elif isinstance(self.meta['tags'], str):
                self.meta['tags'] = [
                    t.strip() for t in self.meta['tags'].split(',')
                ]
                if len(self.meta['tags']) > 1:
                    logging.warn(
                        'Deprecation Warning: Use YAML lists instead '
                        'of CSV for multiple tags. i.e. tags: [guide, '
                        'howto] instead of tags: guide, howto. In {0}.'.format(
                            self.path))
        else:
            self.meta['tags'] = []

        logging.debug('Tags for {0}: {1}'.format(self.meta['slug'],
                                                 self.meta['tags']))

        # pagination
        if 'pagination' not in self.meta:
            self.meta['pagination'] = {}

        if 'cur_page' not in self.meta['pagination']:
            self.meta['pagination']['cur_page'] = 1
        if 'num_pages' not in self.meta['pagination']:
            self.meta['pagination']['num_pages'] = 1

        # template
        try:
            template_type = str(self.meta.get('type', 'default'))
            self.template = self.tmpl_env.get_template(template_type + '.*')
        except jinja2.loaders.TemplateNotFound:
            logging.error(
                'No template "{0}.*" found in template directory. Aborting.'.
                format(template_type))
            sys.exit()
        except AmbiguousTemplate:
            logging.error(
                ('Ambiguous template found. There are two files that '
                 'match "{0}.*". Aborting.').format(template_type))
            sys.exit()

        # url
        parts = {
            'slug': self.meta['slug'],
            'category': '/'.join(self.meta['category']),
            'page': self.meta['pagination']['cur_page'],
            'date': self.meta['date'],
            'datetime': self.meta['datetime'],
            'time': self.meta['time'],
        }
        logging.debug('current page: ' + repr(parts['page']))

        # Pull extensions from the template's real file name.
        parts['ext'] = os.path.splitext(self.template.filename)[1]
        if parts['ext']:
            parts['ext'] = parts['ext'][1:]  # remove leading dot
        # Deprecated
        parts['type'] = parts['ext']
        self.meta['ext'] = parts['ext']

        if parts['page'] == 1:
            parts['page'] = ''

        if 'url' in self.meta:
            logging.debug('Using page url pattern')
            self.url_pattern = self.meta['url']
        else:
            logging.debug('Using global url pattern')
            self.url_pattern = self.options['url_pattern']

        self.meta['url'] = self.url_pattern.format(**parts)

        logging.info('URL pattern is: {0}'.format(self.url_pattern))
        logging.info('URL parts are: {0}'.format(parts))

        # Get rid of extra slashes
        self.meta['url'] = re.sub(r'//+', '/', self.meta['url'])
        logging.debug('{0} will be written to {1}'.format(
            self.meta['slug'], self.meta['url']))

        # If we have been asked to, rip out any plain "index.html"s
        if not self.options['url_include_index']:
            self.meta['url'] = re.sub(r'/index\.html$', '/', self.meta['url'])
        logging.debug('url is: ' + self.meta['url'])

        # subpages
        self.meta['subpages'] = []

        self.engine.run_hook('page.meta.post', self)
예제 #7
0
 def test_noop(self):
     """Tests that is good slug gets passed through unmodified."""
     orig = u'agoodslug'
     slug = orig
     self.assertEqual(slug, util.slugify(orig))
예제 #8
0
 def test_apostrophes(self):
     """Check that apostrophes in words don't end up as ugly seperators"""
     orig = u"Don't use Bob's stuff"
     slug = u'dont-use-bobs-stuff'
     self.assertEqual(slug, util.slugify(orig))
예제 #9
0
 def test_punctuation(self):
     """Check that punctuation is handled right."""
     orig = u"This has... punctuation! *<yo>*."
     slug = u'this-has-punctuation-yo'
     self.assertEqual(slug, util.slugify(orig))
예제 #10
0
 def test_spaces(self):
     """Check that spaces are converted to the seperator character."""
     orig = u'hello world'
     slug = u'hello-world'
     self.assertEqual(slug, util.slugify(orig))
예제 #11
0
 def test_caps(self):
     """Check that case get converted right."""
     orig = u'abcdABCD'
     slug = orig.lower()
     self.assertEqual(slug, util.slugify(orig))
예제 #12
0
파일: page.py 프로젝트: uberj/wok
    def build_meta(self):
        """
        Ensures the guarantees about metadata for documents are valid.

        `page.title` - Will be a string.
        `page.slug` - Will be a string.
        `page.author` - Will have fields `name` and `email`.
        `page.authors` - Will be a list of Authors.
        `page.category` - Will be a list.
        `page.published` - Will exist.
        `page.datetime` - Will be a datetime, or None.
        `page.date` - Will be a date, or None.
        `page.time` - Will be a time, or None.
        `page.tags` - Will be a list.
        `page.url` - Will be the url of the page, relative to the web root.
        `page.subpages` - Will be a list containing every sub page of this page
        """

        if not self.meta:
            self.meta = {}

        # title
        if not 'title' in self.meta:
            self.meta['title'] = '.'.join(self.filename.split('.')[:-1])
            if (self.meta['title'] == ''):
                self.meta['title'] = self.filename

            logging.info("You didn't specify a title in {0}. "
                    "Using the file name as a title.".format(self.filename))

        # slug
        if not 'slug' in self.meta:
            self.meta['slug'] = util.slugify(self.meta['title'])
            logging.debug("You didn't specify a slug, generating it from the title.")
        elif self.meta['slug'] != util.slugify(self.meta['slug']):
            logging.warning('Your slug should probably be all lower case, and '
                'match "[a-z0-9-]*"')

        # authors and author
        authors = self.meta.get('authors', self.meta.get('author', None))
        if isinstance(authors, list):
            self.meta['authors'] = [Author.parse(a) for a in authors]
        elif isinstance(authors, str):
            self.meta['authors'] = [Author.parse(a) for a in authors.split(',')]
            if len(self.meta['authors']) > 1:
                logging.warn('Deprecation Warning: Use YAML lists instead of '
                        'CSV for multiple authors. i.e. ["John Doe", "Jane '
                        'Smith"] instead of "John Doe, Jane Smith". In '
                        '{0}.'.format(self.path))

        elif authors is None:
            if 'authors' in self.options:
                self.meta['authors'] = self.options['authors']
            else:
                self.meta['authors'] = []
        else:
            # wait, what?
            self.meta['authors'] = []
            logging.error(('Authors in {0} is an unknown type. Valid types '
                           'are string or list.').format(self.path))

        if self.meta['authors']:
            self.meta['author'] = self.meta['authors']
        else:
            self.meta['author'] = Author()

        # category
        if 'category' in self.meta:
            self.meta['category'] = self.meta['category'].split('/')
        else:
            self.meta['category'] = []
        if self.meta['category'] == None:
            self.meta = []

        # published
        if not 'published' in self.meta:
            self.meta['published'] = True

        # make_file
        if not 'make_file' in self.meta:
            self.meta['make_file'] = True

        # datetime, date, time
        util.date_and_times(self.meta)

        # tags
        if 'tags' in self.meta:
            if isinstance(self.meta['tags'], list):
                # good
                pass
            elif isinstance(self.meta['tags'], str):
                self.meta['tags'] = [t.strip() for t in
                    self.meta['tags'].split(',')]
                if len(self.meta['tags']) > 1:
                    logging.warn('Deprecation Warning: Use YAML lists instead '
                            'of CSV for multiple tags. i.e. tags: [guide, '
                            'howto] instead of tags: guide, howto. In {0}.'
                            .format(self.path))
        else:
            self.meta['tags'] = []

        logging.debug('Tags for {0}: {1}'.
                format(self.meta['slug'], self.meta['tags']))

        # pagination
        if 'pagination' not in self.meta:
            self.meta['pagination'] = {}

        if 'cur_page' not in self.meta['pagination']:
            self.meta['pagination']['cur_page'] = 1
        if 'num_pages' not in self.meta['pagination']:
            self.meta['pagination']['num_pages'] = 1

        # template
        try:
            template_type = self.meta.get('type', 'default')
            self.template = Page.tmpl_env.get_template(template_type + '.*')
        except jinja2.loaders.TemplateNotFound:
            logging.error('No template "{0}.*" found in template directory. Aborting.'
                    .format(template_type))
            sys.exit()
        except AmbiguousTemplate:
            logging.error(('Ambiguous template found. There are two files that '
                          'match "{0}.*". Aborting.').format(template_type))
            sys.exit()

        # url
        parts = {
            'slug': self.meta['slug'],
            'category': '/'.join(self.meta['category']),
            'page': self.meta['pagination']['cur_page'],
        }
        logging.debug('current page: ' + repr(parts['page']))

        # Pull extensions from the template's real file name.
        match = re.match('.*/[^\.]*\.(.*)$', self.template.filename)
        if match:
            parts['ext'] = match.groups()[0]
        else:
            parts['ext'] = ''
        # Deprecated
        parts['type'] = parts['ext']
        self.meta['ext'] = parts['ext']

        if parts['page'] == 1:
            parts['page'] = ''

        if not 'url' in self.meta:
            self.meta['url'] = self.options['url_pattern'].format(**parts);
        else:
            self.meta['url'] = self.meta['url'].format(**parts);
        # Get rid of extra slashes
        self.meta['url'] = re.sub(r'//+', '/', self.meta['url'])
        logging.debug(self.meta['url'])
        # If we have been asked to, rip out any plain "index.html"s
        if not self.options['url_include_index']:
            self.meta['url'] = re.sub(r'/index\.html$', '/', self.meta['url'])

        # subpages
        self.meta['subpages'] = []
예제 #13
0
    def build_meta(self):
        """
        Ensures the guarantees about metadata for documents are valid.

        `page.title` - Will be a string.
        `page.slug` - Will be a string.
        `page.author` - Will have fields `name` and `email`.
        `page.authors` - Will be a list of Authors.
        `page.category` - Will be a list.
        `page.published` - Will exist.
        `page.datetime` - Will be a datetime.
        `page.date` - Will be a date
        `page.time` - Will be a time
        `page.tags` - Will be a list.
        `page.url` - Will be the url of the page, relative to the web root.
        `page.subpages` - Will be a list containing every sub page of this page
        """

        if not self.meta:
            self.meta = {}

        # title
        if not 'title' in self.meta:
            self.meta['title'] = '.'.join(self.filename.split('.')[:-1])
            if (self.meta['title'] == ''):
                self.meta['title'] = self.filename

            logging.info("You didn't specify a title in {0}. "
                    "Using the file name as a title.".format(self.filename))

        # slug
        if not 'slug' in self.meta:
            self.meta['slug'] = util.slugify(self.meta['title'])
            logging.debug("You didn't specify a slug, generating it from the title.")
        elif self.meta['slug'] != util.slugify(self.meta['slug']):
            logging.warning('Your slug should probably be all lower case, and '
                'match "[a-z0-9-]*"')

        # authors and author
        authors = self.meta.get('authors', self.meta.get('author', None))
        if isinstance(authors, list):
            self.meta['authors'] = [Author.parse(a) for a in authors]
        elif isinstance(authors, str):
            self.meta['authors'] = [Author.parse(a) for a in authors.split(',')]
        elif authors is None:
            if 'authors' in self.options:
                self.meta['authors'] = self.options['authors']
            else:
                self.meta['authors'] = []
        else:
            # wait, what?
            self.meta['authors'] = []
            logging.error(('Authors in {0} is an unknown type. Valid types '
                           'are string or list.').format(self.path))

        if self.meta['authors']:
            self.meta['author'] = self.meta['authors']
        else:
            self.meta['author'] = Author()

        # category
        if 'category' in self.meta:
            self.meta['category'] = self.meta['category'].split('/')
        else:
            self.meta['category'] = []
        if self.meta['category'] == None:
            self.meta = []

        # published
        if not 'published' in self.meta:
            self.meta['published'] = True

        # datetime, date, time
        if 'date' in self.meta:
            self.meta['datetime'] = self.meta['date']

        if not 'datetime' in self.meta:
            logging.debug('Date is none')
            self.meta['datetime'] = None
            self.meta['date'] = None
            self.meta['time'] = None
        else:
            if isinstance(self.meta['datetime'], date):
                d = self.meta['datetime']
                self.meta['datetime'] = datetime(d.year, d.month, d.day)

            self.meta['date'] = self.meta['datetime'].date()
            self.meta['time'] = self.meta['datetime'].time()

        # tags
        if 'tags' in self.meta:
            if isinstance(self.meta['tags'], list):
                # good
                pass
            elif isinstance(self.meta['tags'], str):
                self.meta['tags'] = [t.strip() for t in
                    self.meta['tags'].split(',')]
        else:
            self.meta['tags'] = []

        logging.debug('Tags for {0}: {1}'.
                format(self.meta['slug'], self.meta['tags']))

        # pagination
        if 'pagination' not in self.meta:
            self.meta['pagination'] = {}

        if 'cur_page' not in self.meta['pagination']:
            self.meta['pagination']['cur_page'] = 1
        if 'num_pages' not in self.meta['pagination']:
            self.meta['pagination']['num_pages'] = 1

        # url
        parts = {
            'slug': self.meta['slug'],
            'category': '/'.join(self.meta['category']),
            'page': self.meta['pagination']['cur_page'],
        }
        logging.debug('current page: ' + repr(parts['page']))
        if parts['page'] == 1:
            parts['page'] = ''

        if not 'url' in self.meta:
            self.meta['url'] = self.options['url_pattern'].format(**parts);
        else:
            self.meta['url'] = self.meta['url'].format(**parts);
        # Get rid of extra slashes
        self.meta['url'] = re.sub(r'//+', '/', self.meta['url'])
        logging.debug(self.meta['url'])

        # subpages
        self.meta['subpages'] = []