Example #1
0
 def formatted(self):
     val = self.content
     if val is not None:
         extensions = [
             tables.TableExtension(),
             markdown_extensions.TocExtension(pod=self._doc.pod),
             markdown_extensions.CodeBlockExtension(self._doc.pod),
             markdown_extensions.IncludeExtension(self._doc.pod),
             markdown_extensions.UrlExtension(self._doc.pod),
             'markdown.extensions.fenced_code',
             'markdown.extensions.codehilite',
         ]
         config = self.get_markdown_config('markdown.extensions.codehilite')
         codehilite_config = {
             'pygments_style': 'default',
             'noclasses': True,
             'css_class': 'code',
         }
         if 'theme' in config:
             codehilite_config['pygments_style'] = config.theme
         if 'classes' in config:
             codehilite_config['noclasses'] = not config.classes
         if 'class_name' in config:
             codehilite_config['css_class'] = config.class_name
         extension_configs = {
             'markdown.extensions.codehilite': codehilite_config,
         }
         val = markdown.markdown(
             val.decode('utf-8'), extensions=extensions, extension_configs=extension_configs)
     return val
def write_output(args):
    converter = markdown.Markdown(
        extensions=[
            mdx_tables.TableExtension(),
            mdx_sane_lists.SaneListExtension(),
            mdx_smarty.SmartyExtension(),
            mdx_toc.TocExtension(),
        ],
        output_format='html5',
    )
    with args.input_path.open(encoding=args.encoding) as src_file:
        body = converter.convert(src_file.read())
    with tempfile.NamedTemporaryFile(
            'w',
            encoding=args.encoding,
            dir=args.git_output.dir_path.as_posix(),
            suffix='.html',
            delete=False,
    ) as tmp_out:
        try:
            tmp_out.write(TEMPLATE_HEADER)
            tmp_out.write(body)
            tmp_out.write(TEMPLATE_FOOTER)
            tmp_out.flush()
            os.rename(tmp_out.name, str(args.output_file_path))
        except BaseException:
            os.unlink(tmp_out.name)
            raise
    if args.output_link_path.is_symlink():
        args.output_link_path.unlink()
    args.output_link_path.symlink_to(args.output_file_path.name)
Example #3
0
def _md(x):
    o = markdown.markdown(
        x,
        extensions=[
            tables.TableExtension(),
            fenced_code.FencedCodeExtension(),
            sane_lists.SaneListExtension(),
            markdown_math.MathExtension(),
        ],
    )
    return o
Example #4
0
 def html(self):
   val = self.body
   if val is not None:
     extensions = [
       tables.TableExtension(),
       toc.TocExtension(),
       markdown_extensions.CodeBlockExtension(),
       markdown_extensions.IncludeExtension(self.doc.pod),
       markdown_extensions.UrlExtension(self.doc.pod),
     ]
     val = markdown.markdown(val.decode('utf-8'), extensions=extensions)
   return val
Example #5
0
 def formatted(self):
     val = self.content
     if val is not None:
         extensions = [
             tables.TableExtension(),
             markdown_extensions.TocExtension(pod=self._doc.pod),
             markdown_extensions.CodeBlockExtension(self._doc.pod),
             markdown_extensions.IncludeExtension(self._doc.pod),
             markdown_extensions.UrlExtension(self._doc.pod),
         ]
         val = markdown.markdown(val.decode('utf-8'), extensions=extensions)
     return val
Example #6
0
 def render_to_html_string(self):
     """
     Render the watched document to html, returning the html string
     :return: The rendered HTML of the markdown file
     """
     self.logger.debug('Rendering markdown (%s)', self.filename)
     fake_file = BytesIO()
     markdown.markdownFromFile(input=self.filename,
                               output=fake_file,
                               extensions=[abbr.AbbrExtension(), admonition.AdmonitionExtension(),
                                           attr_list.AttrListExtension(), codehilite.CodeHiliteExtension(),
                                           def_list.DefListExtension(), extra.ExtraExtension(),
                                           fenced_code.FencedCodeExtension(), footnotes.FootnoteExtension(),
                                           legacy_attrs.LegacyAttrExtension(), legacy_em.LegacyEmExtension(),
                                           meta.MetaExtension(), nl2br.Nl2BrExtension(),
                                           sane_lists.SaneListExtension(), smarty.SmartyExtension(),
                                           tables.TableExtension(), toc.TocExtension(),
                                           wikilinks.WikiLinkExtension()])
     fake_file.seek(0)
     return str(fake_file.read(), 'utf-8')
Example #7
0
    def extensions(self):
        """List of enabled extensions for the pod."""
        # Do not cache property so that the extensions are created fresh.
        extensions = [
            tables.TableExtension(),
            markdown_extensions.TocExtension(pod=self.pod),
            markdown_extensions.CodeBlockExtension(self.pod),
            markdown_extensions.IncludeExtension(self.pod),
            markdown_extensions.UrlExtension(self.pod),
            'markdown.extensions.fenced_code',
            'markdown.extensions.codehilite',
        ]

        for config in self.markdown_config:
            if config['kind'] in extensions:
                continue

            if config['kind'].startswith('markdown.extensions'):
                extensions.append(config['kind'])

        return extensions
Example #8
0
    def update_articles(self):
        '''
        Updates articles, folders and categories
        '''

        # Find all characters that are not the os dir separator
        base_depth = self.article_dir.count(os.sep)

        # Loop through articles directory to find categories, folders and
        # articles.
        for cat in os.walk(self.article_dir, topdown=False):
            cat_string = str(cat[0])

            # Don't worry about the top level directory
            if cat_string == self.article_dir:
                continue

            # Check if the category already has an ID
            current_depth = cat_string.count(os.sep) - base_depth
            matches = self.docid_check.search(cat_string)
            if matches:
                # We have an ID, parse out title and ID
                parsed_name = self.docid_re.search(cat_string)

                if current_depth == 1:
                    # Check the DOCID exists
                    category_info = self.categories.get(
                        int(parsed_name.group('docid')))
                    if category_info:
                        # Change the title if there is a discrepancy
                        if category_info['title'] != parsed_name.group(
                                'title'):
                            category_info['title'] = parsed_name.group('title')
                            # NOTE = Any consumer should change title
                            # to new 'title'
                            category_info['action'] = {
                                'action': 'TITLE_CHANGE'
                            }
                    else:
                        # Unknown DOCID - add it in
                        self.categories[parsed_name.group('docid')] = {
                            'title': parsed_name.group('title'),
                            'action': {
                                'action': 'TITLE_CHANGE'
                            }
                        }

                elif current_depth == 2:
                    # Folder

                    # Check the DOCID exists
                    folder_info = self.folders.get(
                        int(parsed_name.group('docid')))
                    if folder_info:
                        # Change the title if there is a discrepancy
                        if folder_info['title'] != parsed_name.group('title'):
                            folder_info['title'] = parsed_name.group('title')
                            # NOTE = Any consumer should change title
                            # to new 'title'
                            folder_info['action'] = {'action': 'TITLE_CHANGE'}
                    else:
                        # Unknown DOCID - add it in
                        self.folders[int(parsed_name.group('docid'))] = {
                            'title': parsed_name.group('title'),
                            'action': {
                                'action': 'TITLE_CHANGE'
                            }
                        }

                    # Now, get the files in this folder, and check their names
                    for listing in os.walk(cat_string, topdown=False):
                        directory = cat_string
                        articles = listing[2]

                        for article in articles:
                            got_id = self.docid_check.search(article)
                            if got_id:
                                # We have an ID, parse out title and ID

                                article_info = self.docid_re.search(article)

                                # Check the DOCID exists
                                article_dict = self.articles.get(
                                    int(article_info.group('docid')))
                                if article_dict:
                                    # Change the title if there is a discrepancy
                                    if article_dict[
                                            'title'] != article_info.group(
                                                'title'):
                                        article_dict[
                                            'title'] = article_info.group(
                                                'title')
                                        # NOTE = Any consumer should change title to new 'title'
                                        article_dict['action'] = {
                                            'action': 'TITLE_CHANGE'
                                        }
                                else:
                                    # Unknown DOCID - add it in
                                    self.articles[int(
                                        parsed_name.group('docid'))] = {
                                            'title':
                                            article_info.group('title'),
                                            'action': {
                                                'action': 'TITLE_CHANGE'
                                            }
                                        }

                            else:
                                # No ID, need a new one
                                # Flag that we need to update

                                article_info = self.title_re.search(article)

                                # Ignore any files that aren'd Markdown
                                if article_info.group('extension'):
                                    # Update the latest article ID
                                    self.counters['article'] += 1

                                    # Flag renaming Category
                                    old_name = '{dir}{sep}{title}{extension}'.format(
                                        dir=directory,
                                        sep=os.sep,
                                        title=article_info.group('title'),
                                        extension=article_info.group(
                                            'extension'))

                                    new_name = '{dir}{sep}{title}--DOCID{docid}{extension}'\
                                        .format(
                                            dir=directory,
                                            sep=os.sep,
                                            title=article_info.group('title'),
                                            docid=self.counters['article'],
                                            extension=article_info.group('extension')
                                        )

                                    # Add information about this article
                                    self.articles[self.counters['article']] = {
                                        'title': article_info.group('title'),
                                        'action': {
                                            'action': 'CREATE',
                                            'from': old_name,
                                            'to': new_name
                                        }
                                    }

            else:
                # No ID, just a title
                # XXX Debugging

                # Get the current relative depth
                # 1 = Category
                # 2 = Folder

                parsed_name = self.title_re.search(cat_string)
                if current_depth == 1:
                    # Category

                    # Flag that we need to update
                    # Update the latest cat ID
                    self.counters['category'] += 1

                    # Flag renaming Category
                    new_name = '{oldname}--DOCID{docid}'.format(
                        oldname=cat_string, docid=self.counters['category'])

                    # Add information about this category
                    self.categories[self.counters['category']] = {
                        'title': parsed_name.group('title'),
                        'action': {
                            'action': 'CREATE',
                            'from': cat_string,
                            'to': new_name
                        }
                    }

                elif current_depth == 2:
                    # Folder

                    # Flag that we need to update
                    # Update the latest folder ID
                    self.counters['folder'] += 1

                    # Flag renaming Category
                    new_name = '{oldname}--DOCID{docid}'.format(
                        oldname=cat_string, docid=self.counters['folder'])

                    # Add information about this folder
                    self.folders[self.counters['folder']] = {
                        'title': parsed_name.group('title'),
                        'action': {
                            'action': 'CREATE',
                            'from': cat_string,
                            'to': new_name
                        }
                    }

                    # Now, get the files in this folder, and check their names
                    for listing in os.walk(cat_string, topdown=False):
                        directory = cat_string
                        articles = listing[2]

                        for article in articles:
                            got_id = self.docid_check.search(article)
                            if got_id:
                                # We have an ID, parse out title and ID
                                article_info = self.docid_re.search(article)

                                # Check the DOCID exists
                                article_dict = self.articles.get(
                                    int(article_info.group('docid')))
                                if article_dict:
                                    # Change the title if there is a discrepancy
                                    if article_dict[
                                            'title'] != article_info.group(
                                                'title'):
                                        article_dict[
                                            'title'] = article_info.group(
                                                'title')
                                        # NOTE = Any consumer should change title to
                                        # new 'title'
                                        article_dict['action'] = {
                                            'action': 'TITLE_CHANGE'
                                        }
                                else:
                                    # Unknown DOCID - add it in
                                    self.articles[article_info.group(
                                        'docid')] = {
                                            'title':
                                            article_info.group('title'),
                                            'action': {
                                                'action': 'TITLE_CHANGE'
                                            }
                                        }
                            else:
                                # No ID, need a new one
                                # Flag that we need to update

                                article_info = self.title_re.search(article)

                                if article_info.group('extension'):
                                    # Update the latest article ID
                                    self.counters['article'] += 1
                                    # Flag renaming Article
                                    oldname = '{dir}{sep}{title}'.format(
                                        dir=directory,
                                        sep=os.sep,
                                        title=article_info.group('title'))

                                    article_name =\
                                        '{oldname}--DOCID{docid}{extension}'\
                                        .format(
                                            oldname=oldname,
                                            docid=self.counters['article'],
                                            extension=article_info.group('extension')
                                        )

                                    # Add information about this article
                                    self.articles[self.counters['article']] = {
                                        'title': article_info.group('title'),
                                        'action': {
                                            'action':
                                            'CREATE',
                                            'from':
                                            '{name}{extension}'.format(
                                                name=oldname,
                                                extension=article_info.group(
                                                    'extension')),
                                            'to':
                                            article_name
                                        }
                                    }

                else:
                    # Too deep, ignore
                    pass

        # We now have all the information required to rename files and folders

        # Start with articles
        for aid, article in self.articles.items():
            # Check if there is an action
            action = article.get('action')
            if action:
                # Need to create a branch
                self.require_change = True
                # If it is a new file, we need to rename it with the new
                # DOCID
                if action['action'] == 'CREATE':
                    os.rename(action['from'], action['to'])
                    self.article_creations[aid] = True
                    self.require_change = True
                elif action['action'] == 'TITLE_CHANGE':
                    self.article_updates[aid] = True
                    self.require_change = True

        # Delete the actions
        for i in self.article_creations:
            del (self.articles[i]['action'])
        for i in self.article_updates:
            del (self.articles[i]['action'])

        # Then to folders
        for fid, folder in self.folders.items():
            # Check if there is an action
            action = folder.get('action')
            if action:
                # Need to create a branch
                self.require_change = True
                # If it is a new file, we need to rename it with the new
                # DOCID
                if action['action'] == 'CREATE':
                    os.rename(action['from'], action['to'])
                    self.folder_creations[fid] = True
                    self.require_change = True
                if action['action'] == 'TITLE_CHANGE':
                    self.folder_updates[fid] = True
                    self.require_change = True

        # Delete the actions
        for i in self.folder_creations:
            del (self.folders[i]['action'])
        for i in self.folder_updates:
            del (self.folders[i]['action'])

        # Finally Categories
        category_creations = []
        for cid, category in self.categories.items():
            # Check if there is an action
            action = category.get('action')
            if action:
                # Need to create a branch
                self.require_change = True

                # If it is a new file, we need to rename it with the new
                # DOCID
                if action['action'] == 'CREATE':
                    os.rename(action['from'], action['to'])
                    self.category_creations[cid] = True
                if action['action'] == 'TITLE_CHANGE':
                    self.category_updates[cid] = True

        # Delete the actions
        for i in self.category_creations:
            del (self.categories[i]['action'])
        for i in self.category_updates:
            del (self.categories[i]['action'])

        # Now that all IDS have been assigned, we can map parent IDS properly
        for cat in os.walk(self.article_dir, topdown=False):
            cat_string = str(cat[0])

            # Don't worry about the top level directory
            if cat_string == self.article_dir:
                continue

            # Check if the category already has an ID
            current_depth = cat_string.count(os.sep) - base_depth
            if current_depth == 1:
                # Categories don't have parents, but we need to record that
                # we found it for deletions.
                matches = self.docid_re.search(cat_string)
                #if not found, need to do something
                cat_id = int(matches.group('docid'))
                if cat_id in self.categories:
                    self.categories[cat_id]['found'] = True
            elif current_depth == 2:
                # Folder
                matches = self.parentid_re.search(cat_string)

                # Set the folder parent
                folder_info = self.folders.get(int(matches.group('docid')))
                folder_info['parent'] = int(matches.group('parent_docid'))
                folder_info['found'] = True

                # Now, get the files in this folder, and check their names
                for listing in os.walk(cat_string, topdown=False):
                    directory = cat_string
                    articles = listing[2]

                    for article in articles:
                        article_info = self.docid_re.search(article)

                        # Only process if it is actually an article
                        # COULD be a .gitignore file/other file that
                        # we don't handle
                        if article_info:
                            # Add the parent folder...
                            tmp_article = self.articles[int(
                                article_info.group('docid'))]
                            tmp_article['parent'] = int(matches.group('docid'))
                            tmp_article['found'] = True

                            # Add a sha1sum of the file
                            with open(
                                    '{directory}{sep}{name}'.format(
                                        directory=cat_string,
                                        sep=os.sep,
                                        name=article), 'r') as f:
                                # Set up our extension
                                # Need to convert the file system path to an encoded URL
                                image_url = directory.replace(
                                    self.article_dir, 'articles')
                                image_ext = imagelinkrewrite.ImageLinkRewriteExtension(
                                    image_file_path=image_url)
                                table_ext = tables.TableExtension()
                                temp = f.read()
                                tmp_article['html'] =\
                                    markdown(
                                        temp,
                                        extensions=[image_ext, table_ext],
                                        output_format='html5'
                                    )
                                tmp_article['sha1'] =\
                                    sha1(tmp_article['html'].encode('utf-8')).hexdigest()

        # Find the deleted and updated items

        # Categories
        for cid, cat in self.categories.items():
            if cat.get('found'):
                del (cat['found'])
                if not cid in self.category_creations:
                    # Check for updates
                    if cat['title'] != self.orig_categories[cid]['title']:
                        self.category_updates[cid] = True
                        self.require_change = True
            else:
                self.category_deletions[cid] = True
                self.require_change = True

        # Folders
        for fid, folder in self.folders.items():
            if folder.get('found'):
                del (folder['found'])
                if not fid in self.folder_creations and fid in self.orig_folders:
                    # Check title and parent change
                    if\
                    folder['title'] != self.orig_folders[fid]['title']\
                    or\
                    folder['parent'] != self.orig_folders[fid]['parent']:
                        self.folder_updates[fid] = True
                        self.require_change = True
            else:
                # Deletion
                self.folder_deletions[fid] = True
                self.require_change = True

        # Articles
        for aid, article in self.articles.items():
            if article.get('found'):
                del (article['found'])
                if not aid in self.article_creations:
                    log.debug('Got to here.... 1')
                    # Check for updates to content, title and parent
                    if\
                    article['sha1'] != self.orig_articles[int(aid)]['sha1']\
                    or\
                    article['title'] != self.orig_articles[int(aid)]['title']\
                    or\
                    article['parent'] != self.orig_articles[int(aid)]['parent']:
                        log.debug('Got to here.... 2')
                        self.article_updates[aid] = True
                        self.require_change = True
                else:
                    log.debug('Got to here.... 3')
            else:
                self.article_deletions[aid] = True
                self.require_change = True