Beispiel #1
0
 def validate_fileinfo(self, relfn, info):
     # layout is mandatory
     if 'layout' not in info:
         raise UrubuError(undef_info_error.format('File', relfn, 'layout'))
     layout = info['layout']
     # modification date, always available
     t = os.path.getmtime(relfn)
     info['mdate'] = datetime.date.fromtimestamp(t)
     # first run a validator if it exist
     if layout in self.validators:
         self.validators[layout](info)
     # a validator may add/modify attributes
     layout = info['layout']
     if layout is None:
         return
     if layout not in self.layouts:
         self.layouts.append(layout)
     # title
     if 'title' not in info:
         raise UrubuError(undef_info_error.format('File', relfn, 'title'))
     # date
     if 'date' in info:
         if not isinstance(info['date'], datetime.date):
             raise UrubuError(date_error.format(relfn))
     # tags
     if 'tags' in info:
         # TODO: make sure it's a list of strings
         if isinstance(info['tags'], str):
             info['tags'] = [info['tags']]
Beispiel #2
0
 def validate_sitereflink(self, id, info):
     if 'title' not in info:
         raise UrubuError(
             undef_meta_error.format('Site reflink', id, 'title'))
     if 'url' not in info:
         raise UrubuError(undef_meta_error.format('Site reflink', id,
                                                  'url'))
Beispiel #3
0
 def validate_sitereflink(self, id, info):
     if 'title' not in info:
         raise UrubuError(_error.undef_reflink_key,
                          fn=id,
                          msg=id + ': title')
     if 'url' not in info:
         raise UrubuError(_error.undef_reflink_key,
                          fn='_site.yml',
                          msg=id + ': url')
Beispiel #4
0
 def resolve_ref(self, ref, info):
     """Resolve a reference."""
     reflinks = self.site['reflinks']
     ref = ref.lower()
     path = os.path.normpath(os.path.join(info['fn'], ref))
     indexfn = info['indexfn']
     id = make_id(get_components(path, hasext=False))
     if ref in reflinks:
         if (ref != id) and (id in reflinks):
             raise UrubuError(_error.ambig_ref, msg=ref, fn=indexfn)
         id = ref
     elif not id in reflinks:
         raise UrubuError(_error.undef_ref, msg=ref, fn=indexfn)
     return reflinks[id]
Beispiel #5
0
 def convert(self):
     for info in self.filelist:
         fn = info['fn']
         with open(fn, encoding='utf-8-sig') as inf:
             src = skip_yamlfm(inf)
         self.md.this = info
         # first process as a template
         try:
             templ = self.env.from_string(src)
             src = templ.render(this=info, site=self.site)
         except:
             exc, msg, tb = sys.exc_info()
             raise UrubuError(str(exc), msg=msg, fn=fn)
         self.md.toc = ''
         info['body'] = self.md.convert(src)
         info['toc'] = ''
         if hasattr(self.md, 'toc'):
             # filter out empty tocs, 35 is the magic length
             if len(self.md.toc) > 35:
                 info['toc'] = self.md.toc
         # markdown support in keys
         mdkeys = [key for key in info if key[-3:] == '.md']
         for mdkey in mdkeys:
             key = mdkey[:-3]
             info[key] = self.md.convert(info[mdkey])
         self.md.reset()
     for info in self.navlist:
         # markdown support in keys
         mdkeys = [key for key in info if key[-3:] == '.md']
         for mdkey in mdkeys:
             key = mdkey[:-3]
             info[key] = self.md.convert(info[mdkey])
         self.md.reset()
Beispiel #6
0
 def add_reflink(self, id, info):
     """Add a valid reflink to the site reflinks."""
     id = id.lower()
     if id in self.site['reflinks']:
         cFile = self.site['reflinks'][id]
         errmsg = "id '{ID}' in {FN} conflicts with {CFN}".\
             format(ID=id, FN=info['fn'], CFN=cFile['fn'])
         raise UrubuError(_error.ambig_refid, msg=errmsg)
     self.site['reflinks'][id] = info
Beispiel #7
0
 def validate_navinfo(self, relfn, info):
     if ('content' not in info) and ('order' not in info):
         # exception: tag folder doesn't require content atribute
         # set it to empty list align with normal folders
         if info['id'] == tagid:
             info['content'] = []
         else:
             raise UrubuError(undef_content_error.format(relfn))
     require_key('content', info, list, relfn)
Beispiel #8
0
    def handleMatch(self, m):
        try:
            ref = m.group(9)
        except IndexError:
            ref = None
        shortref = False
        if not ref:
            # if we got something like "[Google][]" or "[Google]"
            # we'll use "google" as the id
            ref = m.group(2)
            shortref = True

        # Clean up linebreaks in ref
        ref = self.NEWLINE_CLEANUP_RE.sub(' ', ref)

        text = m.group(2)
        id = ref.lower()

        if id in self.markdown.references:
            href, title = self.markdown.references[id]
        else:
            anchor = None
            if '#' in ref:
                ref, anchor = ref.split('#', 1)
            this = self.markdown.this
            if not posixpath.isabs(ref):
                # treat empty ref as reference to current page
                if not ref: 
                    ref = this['components'][-1]
                rootrelpath = '/' + '/'.join(this['components'][:-1])
                id = posixpath.normpath(posixpath.join(rootrelpath, ref))
                id = id.lower()
            else:
                id = ref.lower()
            ref = ref.lower()
            if ref in self.markdown.site['reflinks']:
                if (ref != id) and (id in self.markdown.site['reflinks']):
                    raise UrubuError(_error.ambig_ref_md, msg=ref, fn=this['fn'])
                id = ref
            if id in self.markdown.site['reflinks']:
                item = self.markdown.site['reflinks'][id]
                href, title = item['url'], item['title']
                if shortref:
                    text = title
                    if anchor is not None:
                        text = anchor
                if anchor is not None:
                    anchor = toc.slugify(anchor, '-')
                    href = '%s#%s' % (href, anchor)
                    anchorref = '%s#%s' % (id, anchor)
                    self.markdown.this['_anchorrefs'].add(anchorref)
            else:  # ignore undefined refs
                urubu_warn(_warning.undef_ref_md, msg=ref, fn=this['fn'])
                return None

        return self.makeTag(href, title, text)
Beispiel #9
0
 def pred(item):
     itemcomps = item['components']
     if len(itemcomps) == len(navcomps) + 1 and \
        itemcomps[:-1] == navcomps and \
        itemcomps[-1] != 'index' and \
        item['layout'] is not None:
         if key not in item:
             raise UrubuError(_error.undef_key, msg=key, fn=item['fn'])
         return True
     return False
Beispiel #10
0
    def handleMatch(self, m, data):

        text, index, handled = self.getText(data, m.end(0))
        if not handled:
            return None, None, None

        ref, end, shortref, handled = self.evalRef(data, index, text)
        if not handled:
            return None, None, None

        # Clean up linebreaks in ref
        ref = self.NEWLINE_CLEANUP_RE.sub(' ', ref)

        id = ref.lower()

        if id in self.md.references:
            href, title = self.md.references[id]
        else:
            anchor = None
            if '#' in ref:
                ref, anchor = ref.split('#', 1)
            this = self.md.this
            if not posixpath.isabs(ref):
                # treat empty ref as reference to current page
                if not ref: 
                    ref = this['components'][-1]
                rootrelpath = '/' + '/'.join(this['components'][:-1])
                id = posixpath.normpath(posixpath.join(rootrelpath, ref))
                id = id.lower()
            else:
                id = ref.lower()
            ref = ref.lower()
            if ref in self.md.site['reflinks']:
                if (ref != id) and (id in self.md.site['reflinks']):
                    raise UrubuError(_error.ambig_ref_md, msg=ref, fn=this['fn'])
                id = ref
            if id in self.md.site['reflinks']:
                item = self.md.site['reflinks'][id]
                href, title = item['url'], item['title']
                if shortref:
                    text = title
                    if anchor is not None:
                        text = anchor
                if anchor is not None:
                    anchor = toc.slugify(anchor, '-')
                    href = '%s#%s' % (href, anchor)
                    anchorref = '%s#%s' % (id, anchor)
                    self.md.this['_anchorrefs'].add(anchorref)

            else:  # ignore undefined refs
                urubu_warn(_warning.undef_ref_md, msg=ref, fn=this['fn'])
                return None, None, None

        return self.makeTag(href, title, text), m.start(0), end
Beispiel #11
0
 def validate_fileinfo(self, info):
     fn = info['fn']
     # layout is mandatory
     if 'layout' not in info:
         raise UrubuError(_error.undef_info, msg='layout', fn=fn)
     if 'layout' is None:
         return
     layout = info['layout']
     # modification date, always available
     t = os.path.getmtime(fn)
     info['mdate'] = datetime.date.fromtimestamp(t)
     # first run a validator if it exist
     if layout in self.validators:
         self.validators[layout](info)
     # a validator may add/modify attributes
     layout = info['layout']
     if layout is None:
         return
     if layout not in self.layouts:
         self.layouts.append(layout)
     # title
     if 'title' not in info:
         raise UrubuError(_error.undef_info, msg='title', fn=fn)
     # Support integer titles by converting to string
     # this matters for the json dump for search
     # test type explicitly to avoid problems with unicode titles...
     if isinstance(info['title'], int):
         info['title'] = str(info['title'])
     # date
     if 'date' in info:
         if not isinstance(info['date'], datetime.date):
             raise UrubuError(_error.date_format, fn=fn)
     # tags
     if 'tags' in info:
         # TODO: make sure it's a list of strings
         if isinstance(info['tags'], str):
             info['tags'] = [info['tags']]
Beispiel #12
0
    def get_contentinfo(self):
        """Get info from the markdown content files."""
        pattern = '*.md'
        ignore_patterns = self.get_ignore_patterns()
        for path, dirnames, filenames in os.walk(self.cwd):
            relpath = get_relpath(path, self.cwd)
            if any(fnmatch.fnmatch(relpath, ip) for ip in ignore_patterns):
                continue

            content_found = index_found = False
            for fn in filenames:
                if fnmatch.fnmatch(fn, pattern):
                    # normalize to convert ./foo into foo
                    # to avoid problems with ignore_patterns matching
                    relfn = os.path.normpath(os.path.join(relpath, fn))
                    if any(
                            fnmatch.fnmatch(relfn, ip)
                            for ip in ignore_patterns):
                        continue
                    meta = readers.get_yamlfm(relfn)
                    if meta is None:
                        urubu_warn(_warning.no_yamlfm, fn=relfn)
                        continue
                    fileinfo = self.make_fileinfo(relfn, meta)
                    self.filelist.append(fileinfo)
                    self.process_info(fileinfo, self.site)
                    # validate after file info has been added so it can be used
                    self.validate_fileinfo(fileinfo)
                    self.add_reflink(fileinfo['id'], fileinfo)
                    if fn == 'index.md':
                        index_found = True
                        # start from fileinfo of index file
                        navinfo = self.make_navinfo(relpath, fileinfo)
                        self.navlist.append(navinfo)
                        self.validate_navinfo(navinfo)
                        self.add_reflink(navinfo['id'], navinfo)
                        # add nav info to tag map
                        self.add_info_to_tagmap(navinfo)
                    else:
                        content_found = True
                        # add id for non-index files to tag tags
                        self.add_info_to_tagmap(fileinfo)
            # a folder with content but no index is an error
            if content_found and not index_found:
                raise UrubuError(_error.no_index, msg='', fn=relpath)
    def handleMatch(self, m):
        try:
            ref = m.group(9).lower()
        except IndexError:
            ref = None
        shortref = False
        if not ref:
            # if we got something like "[Google][]" or "[Google]"
            # we'll use "google" as the id
            ref = m.group(2).lower()
            shortref = True

        text = m.group(2)
        # Clean up linebreaks in ref 
        ref = self.NEWLINE_CLEANUP_RE.sub(' ', ref)
        if ref in self.markdown.references:
            href, title = self.markdown.references[ref]
        else: 
            this = self.markdown.this
            if not posixpath.isabs(ref):
                rootrelpath = '/' +  '/'.join(this['components'][:-1])
                id = posixpath.normpath(posixpath.join(rootrelpath, ref))
                id = id.lower()
            else:
                id = ref
            anchor = None
            if '#' in id and id not in self.markdown.site['reflinks']:
                id, anchor = id.split('#', 1)
            if ref in self.markdown.site['reflinks']:
                if (ref != id) and (id in self.markdown.site['reflinks']):
                    raise UrubuError(ambig_ref_error.format(ref, this['fn']))
                id = ref
            if id in self.markdown.site['reflinks']:
                item = self.markdown.site['reflinks'][id]
                href, title = item['url'], item['title']
                if shortref:
                    text = title
                if anchor is not None:
                    href = '%s#%s' % (href, anchor)
            else: # ignore undefined refs
                warn(undef_ref_warning.format(ref, this['fn']), UrubuWarning)
                return None

        return self.makeTag(href, title, text)
Beispiel #14
0
 def add_reflink(self, id, info):
     """Add a valid reflink to the site reflinks."""
     id = id.lower()
     if id in self.site['reflinks']:
         raise UrubuError(_error.ambig_refid, msg=id)
     self.site['reflinks'][id] = info