def parse(requestPath, fileLocation, content, lang='en'):
  context = {
    'lang': lang,
    'requestPath': requestPath.replace('/index', ''),
    'bodyClass': 'devsite-doc-page',
    'servedFromAppEngine': SERVED_FROM_AE
  }

  ## Get the HTML tag
  htmlTag = re.search(r'<html.*?>', content)
  if htmlTag is None:
    logging.warning('Does not contain <html> root element')
  else:
    htmlTag = htmlTag.group(0)
    # Check the HTML tag contains the devsite
    if htmlTag.find('devsite') == -1:
      return content

  # Isolate the <head>
  headStart = content.find('<head')
  headEnd = content.find('</head>')
  head = content[headStart:headEnd].strip()

  # Isolate the <body>
  bodyStart = content.find('<body')
  bodyEnd = content.rfind('</body>')
  body = content[bodyStart:bodyEnd].strip()
  body = re.sub(r'<body.*?>', '', body)

  # Remove any comments {# something #}
  body = re.sub(r'{#.+?#}', '', body)
  body = re.sub(r'{% comment %}.*?{% endcomment %}(?ms)', '', body)

  # Render any DevSite specific tags
  body = devsiteHelper.renderDevSiteContent(body, lang)

  # Read the project.yaml file
  projectPath = re.search('name=\"project_path\" value=\"(.*?)\"', head)
  projectPath = projectPath.group(1)
  projectYaml = yaml.load(devsiteHelper.readFile(projectPath, lang))
  context['projectYaml'] = projectYaml

  # Read the parent project.yaml file if applicable
  parentProjectYaml = None
  if 'parent_project_metadata_path' in projectYaml:
    parentprojectPath = projectYaml['parent_project_metadata_path']
    parentProjectYaml = yaml.load(devsiteHelper.readFile(parentprojectPath, lang))

  # Read the book.yaml file and generate the left hand nav
  bookPath = re.search('name=\"book_path\" value=\"(.*?)\"', head)
  bookPath = bookPath.group(1)
  bookYaml = devsiteHelper.parseBookYaml(bookPath, lang)
  context['bookYaml'] = devsiteHelper.expandBook(bookYaml)
  context['lowerTabs'] = devsiteHelper.getLowerTabs(bookYaml)
  context['renderedLeftNav'] = devsiteHelper.getLeftNav(requestPath, bookYaml)

  # Get the logo row (TOP ROW) icon
  context['logoRowIcon'] = projectYaml['icon']['path']

  # Get the logo row (TOP ROW) title
  if parentProjectYaml:
    context['logoRowTitle'] = parentProjectYaml['name']
  else:
    context['logoRowTitle'] = projectYaml['name']

  # Get the header title & description
  context['headerTitle'] = projectYaml['name']
  # headerDescription is rarely shown, hiding temporarily
  # context['headerDescription'] = projectYaml['description']

  # Read the page title
  pageTitle = []
  titleRO = re.search('<title>(.*?)</title>', head)
  if titleRO:
    title = titleRO.group(1)
    pageTitle.append(title)
    if body.find('<h1>') == -1:
      body = '<h1 class="page-title">' + title + '</h1>\n\n' + body
  pageTitle.append(projectYaml['name'])
  pageTitle.append('WebFu Staging')
  context['pageTitle'] = ' | '.join(pageTitle)

  # Get the footer path & read/parse the footer file.
  footerPath = projectYaml['footer_path']
  footers = yaml.load(devsiteHelper.readFile(footerPath, lang))['footer']
  for item in footers:
    if 'promos' in item:
      context['footerPromos'] = item['promos']
    elif 'linkboxes' in item:
      context['footerLinks'] = item['linkboxes']

  # Replaces <pre> tags with prettyprint enabled tags
  body = re.sub(r'^<pre>(?m)', r'<pre class="prettyprint devsite-code-highlight">', body)
  # Adds code highlighting support, which requires devsite-code-highlight
  body = re.sub(r'^<pre class="prettyprint">(?m)', r'<pre class="prettyprint devsite-code-highlight">', body)

  context['content'] = body

  # Checks if the page should be displayed in full width mode
  fullWidth = re.search('name=\"full_width\" value=\"true\"', head)
  if fullWidth:
    context['fullWidth'] = True

  # # Build the table of contents & transform so it fits within DevSite
  context['renderedTOC'] = '<b>TOC Not Implemented</b> for DevSite HTML Pages'

  gitHubEditUrl = 'https://github.com/google/WebFundamentals/blob/'
  gitHubEditUrl += 'master/src/content/'
  gitHubEditUrl += fileLocation.replace(SOURCE_PATH, '')
  context['gitHubEditUrl'] = gitHubEditUrl

  gitHubIssueUrl = 'https://github.com/google/WebFundamentals/issues/'
  gitHubIssueUrl += 'new?title=Feedback for: ' + context['pageTitle'] + ' ['
  gitHubIssueUrl += lang + ']&body='
  gitHubIssueUrl += gitHubEditUrl
  context['gitHubIssueUrl'] = gitHubIssueUrl

  # Renders the content into the template
  return render('gae/page-article.html', context)
Esempio n. 2
0
def parse(requestPath, fileLocation, content, lang='en'):
    context = {
        'lang': lang,
        'requestPath': requestPath.replace('/index', ''),
        'bodyClass': 'devsite-doc-page',
        'servedFromAppEngine': SERVED_FROM_AE
    }

    ## Get the HTML tag
    htmlTag = re.search(r'<html.*?>', content)
    if htmlTag is None:
        logging.warning('Does not contain <html> root element')
    else:
        htmlTag = htmlTag.group(0)
        # Check the HTML tag contains the devsite
        if htmlTag.find('devsite') == -1:
            return content

    # Isolate the <head>
    headStart = content.find('<head')
    headEnd = content.find('</head>')
    head = content[headStart:headEnd].strip()

    # Isolate the <body>
    bodyStart = content.find('<body')
    bodyEnd = content.rfind('</body>')
    body = content[bodyStart:bodyEnd].strip()
    body = re.sub(r'<body.*?>', '', body)

    # Remove any comments {# something #}
    body = re.sub(r'{#.+?#}', '', body)
    body = re.sub(r'{% comment %}.*?{% endcomment %}(?ms)', '', body)

    # Render any DevSite specific tags
    body = devsiteHelper.renderDevSiteContent(body, lang)

    # Read the project.yaml file
    projectPath = re.search('name=\"project_path\" value=\"(.*?)\"', head)
    projectPath = projectPath.group(1)
    projectYaml = yaml.load(devsiteHelper.readFile(projectPath, lang))
    context['projectYaml'] = projectYaml

    # Read the parent project.yaml file if applicable
    parentProjectYaml = None
    if 'parent_project_metadata_path' in projectYaml:
        parentprojectPath = projectYaml['parent_project_metadata_path']
        parentProjectYaml = yaml.load(
            devsiteHelper.readFile(parentprojectPath, lang))

    # Read the book.yaml file and generate the left hand nav
    bookPath = re.search('name=\"book_path\" value=\"(.*?)\"', head)
    bookPath = bookPath.group(1)
    bookYaml = devsiteHelper.parseBookYaml(bookPath, lang)
    context['bookYaml'] = devsiteHelper.expandBook(bookYaml)
    context['lowerTabs'] = devsiteHelper.getLowerTabs(bookYaml)
    context['renderedLeftNav'] = devsiteHelper.getLeftNav(
        requestPath, bookYaml)

    # Get the logo row (TOP ROW) icon
    context['logoRowIcon'] = projectYaml['icon']['path']

    # Get the logo row (TOP ROW) title
    if parentProjectYaml:
        context['logoRowTitle'] = parentProjectYaml['name']
    else:
        context['logoRowTitle'] = projectYaml['name']

    # Get the header title & description
    context['headerTitle'] = projectYaml['name']
    # headerDescription is rarely shown, hiding temporarily
    # context['headerDescription'] = projectYaml['description']

    # Read the page title
    pageTitle = []
    titleRO = re.search('<title>(.*?)</title>', head)
    if titleRO:
        title = titleRO.group(1)
        pageTitle.append(title)
        if body.find('<h1>') == -1:
            body = '<h1 class="page-title">' + title + '</h1>\n\n' + body
    pageTitle.append(projectYaml['name'])
    pageTitle.append('WebFu Staging')
    context['pageTitle'] = ' | '.join(pageTitle)

    # Get the footer path & read/parse the footer file.
    footerPath = projectYaml['footer_path']
    footers = yaml.load(devsiteHelper.readFile(footerPath, lang))['footer']
    for item in footers:
        if 'promos' in item:
            context['footerPromos'] = item['promos']
        elif 'linkboxes' in item:
            context['footerLinks'] = item['linkboxes']

    # Replaces <pre> tags with prettyprint enabled tags
    body = re.sub(r'^<pre>(?m)',
                  r'<pre class="prettyprint devsite-code-highlight">', body)
    # Adds code highlighting support, which requires devsite-code-highlight
    body = re.sub(r'^<pre class="prettyprint">(?m)',
                  r'<pre class="prettyprint devsite-code-highlight">', body)

    context['content'] = body

    # Checks if the page should be displayed in full width mode
    fullWidth = re.search('name=\"full_width\" value=\"true\"', head)
    if fullWidth:
        context['fullWidth'] = True

    # # Build the table of contents & transform so it fits within DevSite
    context[
        'renderedTOC'] = '<b>TOC Not Implemented</b> for DevSite HTML Pages'

    gitHubEditUrl = 'https://github.com/google/WebFundamentals/blob/'
    gitHubEditUrl += 'main/src/content/'
    gitHubEditUrl += fileLocation.replace(SOURCE_PATH, '')
    context['gitHubEditUrl'] = gitHubEditUrl

    gitHubIssueUrl = 'https://github.com/google/WebFundamentals/issues/'
    gitHubIssueUrl += 'new?title=Feedback for: ' + context['pageTitle'] + ' ['
    gitHubIssueUrl += lang + ']&body='
    gitHubIssueUrl += gitHubEditUrl
    context['gitHubIssueUrl'] = gitHubIssueUrl

    # Renders the content into the template
    return render('gae/page-article.html', context)
def getPage(requestPath, lang):
  response = None
  title = 'Web Fundamentals'
  leftNav = '- No Left Nav Found - '
  toc = '- No TOC Found - '
  banner = devsiteHelper.getAnnouncementBanner(lang)
  template = 'gae/article.tpl'
  fileLocations = [
    os.path.join(SOURCE_PATH, lang, requestPath) + '.md',
    os.path.join(SOURCE_PATH, 'en', requestPath) + '.md',
    os.path.join(SOURCE_PATH, lang, requestPath) + '.jshtml',
    os.path.join(SOURCE_PATH, 'en', requestPath) + '.jshtml',
  ]
  for fileLocation in fileLocations:
    if os.path.isfile(fileLocation):
      content = open(fileLocation, 'r').read()
      content = content.decode('utf8')

      # If it's a .jshtml file, just serve it.
      if fileLocation.endswith('.jshtml'):
        return content

      dateUpdated = re.search(r"{# wf_updated_on:[ ]?(.*)[ ]?#}", content)
      if dateUpdated is None:
        logging.warn('Missing wf_updated_on tag.')
        dateUpdated = 'Unknown'
      else:
        dateUpdated = dateUpdated.group(1)

      ## Injects markdown includes into the markdown as appropriate
      includes = re.findall(r'^<<.+?\.md>>(?m)', content)
      for includeTag in includes:
        fileName = includeTag.replace('<<', '').replace('>>', '')
        fileName = os.path.join(os.path.dirname(fileLocation), fileName)
        include = devsiteHelper.readFile(fileName, lang)
        if include is None:
          include = 'Warning: Unable to find included markdown file.\n\n'
        content = content.replace(includeTag, include)

      # Remove any comments {# something #} from the markdown
      content = re.sub(r'{#.+?#}', '', content)
      content = re.sub(r'{% comment %}.*?{% endcomment %}(?ms)', '', content)

      # Show warning for unsupported elements
      for tag in UNSUPPORTED_TAGS:
        if re.search(tag, content) is not None:
          logging.error(' - Unsupported tag: ' + tag)
          replaceWith = '<aside class="warning">Web<strong>Fundamentals</strong>: '
          replaceWith += '<span>Unsupported tag: <code>' + tag + '</code></span></aside>'
          content = re.sub(tag, replaceWith, content)

      # Show warning for template tags
      if re.search('{{', content) is not None:
        logging.warn(' - Warning: possible unescaped template tag')

      # Render any DevSite specific tags
      content = devsiteHelper.renderDevSiteContent(content, lang)

      # If it's a markdown file, parse it to HTML
      if fileLocation.endswith('.md'):
        content = re.sub(r'^Success: (.*?)\n^\n(?ms)', r'<aside class="success" markdown="1"><strong>Success:</strong> <span>\1</span></aside>', content)
        content = re.sub(r'^Dogfood: (.*?)\n^\n(?ms)', r'<aside class="dogfood" markdown="1"><strong>Dogfood:</strong> <span>\1</span></aside>', content)
        content = re.sub(r'^Note: (.*?)\n^\n(?ms)', r'<aside class="note" markdown="1"><strong>Note:</strong> <span>\1</span></aside>', content)
        content = re.sub(r'^Caution: (.*?)\n^\n(?ms)', r'<aside class="caution" markdown="1"><strong>Caution:</strong> <span>\1</span></aside>', content)
        content = re.sub(r'^Warning: (.*?)\n^\n(?ms)', r'<aside class="warning" markdown="1"><strong>Warning:</strong> <span>\1</span></aside>', content)

        # Adds a set of markdown extensions available to us on DevSite
        ext = [
          'markdown.extensions.attr_list', # Adds support for {: #someid }
          'markdown.extensions.meta', # Removes the meta data from the top of the doc
          'markdown.extensions.toc', # Generate the TOC for the right side
          'markdown.extensions.tables', # Support for Markdown Tables
          'markdown.extensions.extra', # Support for markdown='1' in tags
          'markdown.extensions.def_list' # Support for definition lists
        ]
        md = markdown.Markdown(extensions=ext)
        content = md.convert(content)

        # Reads the book.yaml file and generate the lefthand nav
        if 'book_path' in md.Meta and len(md.Meta['book_path']) == 1:
          bookPath = md.Meta['book_path'][0]
          leftNav = devsiteHelper.getLeftNav(requestPath, bookPath, lang)

        # Checks if the page should be displayed in full width mode
        if 'full_width' in md.Meta and len(md.Meta['full_width']) == 1:
          fullWidth = md.Meta['full_width'][0]
          if fullWidth.lower().strip() == 'true':
            template = 'gae/home.tpl'

        # Build the table of contents & transform so it fits within DevSite
        toc = md.toc
        toc = toc.strip()
        # Strips the outer wrapper and the page title from the doc
        toc = re.sub(r'<div class="toc">(.*?<ul>){2}(?s)', '', toc)
        toc = re.sub(r'</ul>\s*</li>\s*</ul>\s*</div>(?s)', '', toc)
        # Add appropriate classes
        toc = re.sub(r'<ul>', '<ul class="devsite-page-nav-list">', toc)
        toc = re.sub(r'<a href', '<a class="devsite-nav-title" href', toc)
        toc = re.sub(r'<li>', '<li class="devsite-nav-item">', toc)

      # Replaces <pre> tags with prettyprint enabled tags
      content = re.sub(r'^<pre>(?m)', r'<pre class="prettyprint">', content)

      # Get the page title from the markup.
      titleRO = re.search(r'<h1 class="page-title".*?>(.*?)<\/h1>', content)
      if titleRO:
        title = titleRO.group(1)

      gitHubEditUrl = 'https://github.com/google/WebFundamentals/blob/'
      gitHubEditUrl += 'master/src/content/'
      gitHubEditUrl += fileLocation.replace(SOURCE_PATH, '')

      gitHubIssueUrl = 'https://github.com/google/WebFundamentals/issues/'
      gitHubIssueUrl += 'new?title=Feedback for: ' + title + ' ['
      gitHubIssueUrl += lang + ']&body='
      gitHubIssueUrl += gitHubEditUrl


      # Renders the content into the template
      response = render(template, {
        'title': title,
        'announcementBanner': banner,
        'gitHubIssueUrl': gitHubIssueUrl,
        'gitHubEditUrl': gitHubEditUrl,
        'requestPath': requestPath.replace('index', ''),
        'leftNav': leftNav,
        'content': content,
        'toc': toc,
        'dateUpdated': dateUpdated,
        'lang': lang}
      )
      break

  return response
Esempio n. 4
0
def parse(requestPath, fileLocation, content, lang='en'):
    context = {
        'lang': lang,
        'requestPath': requestPath.replace('/index', ''),
        'bodyClass': 'devsite-doc-page',
        'servedFromAppEngine': SERVED_FROM_AE
    }

    ## Injects markdown includes into the markdown as appropriate
    includes = re.findall(r'^<<.+?\.md>>(?m)', content)
    for includeTag in includes:
        fileName = includeTag.replace('<<', '').replace('>>', '')
        fileName = os.path.join(os.path.dirname(fileLocation), fileName)
        include = devsiteHelper.readFile(fileName, lang)
        if include is None:
            include = 'Warning: Unable to find included markdown file.\n\n'
        content = content.replace(includeTag, include)

    # Remove any comments {# something #}
    content = re.sub(r'{#.+?#}', '', content)
    content = re.sub(r'{% comment %}.*?{% endcomment %}(?ms)', '', content)

    # Remove any markdown=1 since it's not supported
    content = re.sub(r'markdown=[\'\"]?1[\'\"]?', '', content)

    # Render any DevSite specific tags
    content = devsiteHelper.renderDevSiteContent(content, lang)

    # Turn Callouts into the appropriate HTML elements
    content = re.sub(
        r'^Note: (.*?)\n^\n(?ms)',
        r'<aside class="note" markdown="1"><strong>Note:</strong> <span>\1</span></aside>',
        content)
    content = re.sub(
        r'^Caution: (.*?)\n^\n(?ms)',
        r'<aside class="caution" markdown="1"><strong>Caution:</strong> <span>\1</span></aside>',
        content)
    content = re.sub(
        r'^Warning: (.*?)\n^\n(?ms)',
        r'<aside class="warning" markdown="1"><strong>Warning:</strong> <span>\1</span></aside>',
        content)
    content = re.sub(
        r'^Key Point: (.*?)\n^\n(?ms)',
        r'<aside class="key-point" markdown="1"><strong>Key Point:</strong> <span>\1</span></aside>',
        content)
    content = re.sub(
        r'^Key Term: (.*?)\n^\n(?ms)',
        r'<aside class="key-term" markdown="1"><strong>Key Term:</strong> <span>\1</span></aside>',
        content)
    content = re.sub(
        r'^Objective: (.*?)\n^\n(?ms)',
        r'<aside class="objective" markdown="1"><strong>Objective:</strong> <span>\1</span></aside>',
        content)
    content = re.sub(
        r'^Success: (.*?)\n^\n(?ms)',
        r'<aside class="success" markdown="1"><strong>Success:</strong> <span>\1</span></aside>',
        content)
    content = re.sub(
        r'^Dogfood: (.*?)\n^\n(?ms)',
        r'<aside class="dogfood" markdown="1"><strong>Dogfood:</strong> <span>\1</span></aside>',
        content)

    # Adds a set of markdown extensions available to us on DevSite
    ext = [
        'markdown.extensions.attr_list',  # Adds support for {: #someid }
        'markdown.extensions.meta',  # Removes the meta data from the top of the doc
        'markdown.extensions.toc',  # Generate the TOC for the right side
        'markdown.extensions.tables',  # Support for Markdown Tables
        'markdown.extensions.def_list',  # Support for definition lists
        'markdown.extensions.extra'  #
    ]
    md = markdown.Markdown(extensions=ext)
    content = md.convert(content)

    # Replaces <pre> tags with prettyprint enabled tags
    content = re.sub(r'^<pre>(?m)',
                     r'<pre class="prettyprint devsite-code-highlight">',
                     content)
    # Adds code highlighting support, which requires devsite-code-highlight
    content = re.sub(r'^<pre class="prettyprint">(?m)',
                     r'<pre class="prettyprint devsite-code-highlight">',
                     content)

    # Save the content
    context['content'] = content

    # Get the project_path and read/parse the project file.
    projectPath = md.Meta['project_path'][0]
    projectYaml = yaml.load(devsiteHelper.readFile(projectPath, lang))
    context['projectYaml'] = projectYaml

    # Read the parent project.yaml file if applicable
    parentProjectYaml = None
    if 'parent_project_metadata_path' in projectYaml:
        parentprojectPath = projectYaml['parent_project_metadata_path']
        parentProjectYaml = yaml.load(
            devsiteHelper.readFile(parentprojectPath, lang))

    # Reads the book.yaml file and generate the lefthand nav
    bookPath = md.Meta['book_path'][0]
    bookYaml = devsiteHelper.parseBookYaml(bookPath, lang)
    context['bookYaml'] = devsiteHelper.expandBook(bookYaml)
    # context['lowerTabs'] = devsiteHelper.getLowerTabs(bookYaml)
    context['renderedLeftNav'] = devsiteHelper.getLeftNav(
        requestPath, bookYaml)

    lowerTabs = devsiteHelper.getLowerTabs(bookYaml)
    context['lowerTabs'] = lowerTabs

    # Get the logo row (TOP ROW) icon
    context['logoRowIcon'] = projectYaml['icon']['path']

    # Get the logo row (TOP ROW) title
    if parentProjectYaml:
        context['logoRowTitle'] = parentProjectYaml['name']
    else:
        context['logoRowTitle'] = projectYaml['name']

    # Get the header title & description
    context['headerTitle'] = projectYaml['name']
    # headerDescription is rarely shown, hiding temporarily
    # context['headerDescription'] = projectYaml['description']

    # Get the page title
    pageTitle = []
    titleRO = re.search(r'<h1 class="page-title".*?>(.*?)<\/h1>', content)
    if titleRO:
        pageTitle.append(titleRO.group(1))
    pageTitle.append(projectYaml['name'])
    pageTitle.append('WebFu Staging')
    context['pageTitle'] = ' | '.join(pageTitle)

    # Get the footer path & read/parse the footer file.
    footerPath = projectYaml['footer_path']
    footers = yaml.load(devsiteHelper.readFile(footerPath, lang))['footer']
    for item in footers:
        if 'promos' in item:
            context['footerPromos'] = item['promos']
        elif 'linkboxes' in item:
            context['footerLinks'] = item['linkboxes']

    if 'full_width' in md.Meta and len(md.Meta['full_width']) == 1:
        context['fullWidth'] = True

    # Build the table of contents & transform so it fits within DevSite
    toc = md.toc
    toc = toc.strip()
    # Strips the outer wrapper and the page title from the doc
    toc = re.sub(r'<div class="toc">(.*?<ul>){2}(?s)', '', toc)
    toc = re.sub(r'</ul>\s*</li>\s*</ul>\s*</div>(?s)', '', toc)
    # Add appropriate classes
    toc = re.sub(r'<ul>', '<ul class="devsite-page-nav-list">', toc)
    toc = re.sub(r'<a href', '<a class="devsite-nav-title" href', toc)
    toc = re.sub(r'<li>', '<li class="devsite-nav-item">', toc)
    context['renderedTOC'] = toc

    gitHubEditUrl = 'https://github.com/google/WebFundamentals/blob/'
    gitHubEditUrl += 'main/src/content/'
    gitHubEditUrl += fileLocation.replace(SOURCE_PATH, '')
    context['gitHubEditUrl'] = gitHubEditUrl

    gitHubIssueUrl = 'https://github.com/google/WebFundamentals/issues/'
    gitHubIssueUrl += 'new?title=Feedback for: ' + context['pageTitle'] + ' ['
    gitHubIssueUrl += lang + ']&body='
    gitHubIssueUrl += gitHubEditUrl
    context['gitHubIssueUrl'] = gitHubIssueUrl

    return render('gae/page-article.html', context)
def parse(requestPath, fileLocation, rawYaml, lang='en'):
  context = {
    'lang': lang,
    'requestPath': requestPath.replace('/index', ''),
    'bodyClass': 'devsite-landing-page',
    'servedFromAppEngine': SERVED_FROM_AE
  }

  # Parse the Yaml
  parsedYaml = yaml.load(rawYaml)
  page = parsedYaml['landing_page']
  if 'body_class' in page:
    context['bodyClass'] += ' ' + page['body_class']

  # Get the project_path and read/parse the project file.
  projectPath = parsedYaml['project_path']
  projectYaml = yaml.load(devsiteHelper.readFile(projectPath, lang))
  context['projectYaml'] = projectYaml

  # Read the parent project.yaml file if applicable
  parentProjectYaml = None
  if 'parent_project_metadata_path' in projectYaml:
    parentprojectPath = projectYaml['parent_project_metadata_path']
    parentProjectYaml = yaml.load(devsiteHelper.readFile(parentprojectPath, lang))

  # Get the book path and read/parse the book file, then add the lower tabs.
  bookPath = parsedYaml['book_path']
  bookYaml = devsiteHelper.parseBookYaml(bookPath, lang)
  context['bookYaml'] = devsiteHelper.expandBook(bookYaml)
  context['lowerTabs'] = devsiteHelper.getLowerTabs(bookYaml)

  # Get the row or column count for each row
  for row in page['rows']:
    if 'items' in row:
      count = len(row['items'])
      row['itemCount'] = count
      for item in row['items']:
        if 'custom_html' in item:
          c = item['custom_html']
          item['custom_html'] = devsiteHelper.renderDevSiteContent(c, lang)
    elif 'columns' in row:
      count = len(row['columns'])
      row['itemCount'] = count
    elif 'custom_html' in row:
      row['itemCount'] = 1
      c = row['custom_html']
      row['custom_html'] = devsiteHelper.renderDevSiteContent(c, lang)
  context['rows'] = page['rows']

  # Get the custom CSS path
  if 'custom_css_path' in page:
    context['customCSSPath'] = page['custom_css_path']

  # Get the logo row (TOP ROW) icon
  context['logoRowIcon'] = projectYaml['icon']['path']

  # Get the logo row (TOP ROW) title
  if 'header' in page and 'name' in page['header']:
    context['logoRowTitle'] = page['header']['name']
  elif parentProjectYaml:
    context['logoRowTitle'] = parentProjectYaml['name']
  else:
    context['logoRowTitle'] = projectYaml['name']

  # Get the custom_html for the header if appropriate
  if 'header' in page and 'custom_html' in page['header']:
    context['customHeader'] = page['header']['custom_html']

  # Get the header title
  if 'parent_project_metadata_path' in projectYaml:
    context['headerTitle'] = projectYaml['name']
  elif 'title' in parsedYaml:
    context['headerTitle'] = parsedYaml['title']
  else:
    context['headerTitle'] = projectYaml['name']

  # Get the header description
  if 'header' in page and 'description' in page['header']:
    context['headerDescription'] = page['header']['description']
  else:
    context['headerDescription'] = projectYaml['description']

  # Get the header buttons
  if 'header' in page and 'buttons' in page['header']:
    context['headerButtons'] = page['header']['buttons']

  # Set the page title
  pageTitle = []
  if 'title' in parsedYaml:
    pageTitle.append(parsedYaml['title'])
  pageTitle.append(projectYaml['name'])
  pageTitle.append('WebFu Staging')
  context['pageTitle'] = ' | '.join(pageTitle)

  # Get the footer path & read/parse the footer file.
  footerPath = projectYaml['footer_path']
  footers = yaml.load(devsiteHelper.readFile(footerPath, lang))['footer']
  for item in footers:
    if 'promos' in item:
      context['footerPromos'] = item['promos']
    elif 'linkboxes' in item:
      context['footerLinks'] = item['linkboxes']

  return render('gae/page-landing.html', context)
Esempio n. 6
0
def parse(requestPath, fileLocation, rawYaml, lang='en'):
    context = {
        'lang': lang,
        'requestPath': requestPath.replace('/index', ''),
        'bodyClass': 'devsite-landing-page',
        'servedFromAppEngine': SERVED_FROM_AE
    }

    # Parse the Yaml
    parsedYaml = yaml.load(rawYaml)
    page = parsedYaml['landing_page']

    # Get the project_path and read/parse the project file.
    projectPath = parsedYaml['project_path']
    projectYaml = yaml.load(devsiteHelper.readFile(projectPath, lang))
    context['projectYaml'] = projectYaml

    # Read the parent project.yaml file if applicable
    parentProjectYaml = None
    if 'parent_project_metadata_path' in projectYaml:
        parentprojectPath = projectYaml['parent_project_metadata_path']
        parentProjectYaml = yaml.load(
            devsiteHelper.readFile(parentprojectPath, lang))

    # Get the book path and read/parse the book file, then add the lower tabs.
    bookPath = parsedYaml['book_path']
    bookYaml = devsiteHelper.parseBookYaml(bookPath, lang)
    context['bookYaml'] = devsiteHelper.expandBook(bookYaml)
    context['lowerTabs'] = devsiteHelper.getLowerTabs(bookYaml)

    # Get the row or column count for each row
    for row in page['rows']:
        if 'items' in row:
            count = len(row['items'])
            row['itemCount'] = count
            for item in row['items']:
                if 'custom_html' in item:
                    c = item['custom_html']
                    item['custom_html'] = devsiteHelper.renderDevSiteContent(
                        c, lang)
        elif 'columns' in row:
            count = len(row['columns'])
            row['itemCount'] = count
        elif 'custom_html' in row:
            row['itemCount'] = 1
            c = row['custom_html']
            row['custom_html'] = devsiteHelper.renderDevSiteContent(c, lang)
    context['rows'] = page['rows']

    # Get the custom CSS path
    if 'custom_css_path' in page:
        context['customCSSPath'] = page['custom_css_path']

    # Get the logo row (TOP ROW) icon
    context['logoRowIcon'] = projectYaml['icon']['path']

    # Get the logo row (TOP ROW) title
    if 'header' in page and 'name' in page['header']:
        context['logoRowTitle'] = page['header']['name']
    elif parentProjectYaml:
        context['logoRowTitle'] = parentProjectYaml['name']
    else:
        context['logoRowTitle'] = projectYaml['name']

    # Get the custom_html for the header if appropriate
    if 'header' in page and 'custom_html' in page['header']:
        context['customHeader'] = page['header']['custom_html']

    # Get the header title
    if 'parent_project_metadata_path' in projectYaml:
        context['headerTitle'] = projectYaml['name']
    elif 'title' in parsedYaml:
        context['headerTitle'] = parsedYaml['title']
    else:
        context['headerTitle'] = projectYaml['name']

    # Get the header description
    if 'header' in page and 'description' in page['header']:
        context['headerDescription'] = page['header']['description']
    else:
        context['headerDescription'] = projectYaml['description']

    # Get the header buttons
    if 'header' in page and 'buttons' in page['header']:
        context['headerButtons'] = page['header']['buttons']

    # Set the page title
    pageTitle = []
    if 'title' in parsedYaml:
        pageTitle.append(parsedYaml['title'])
    pageTitle.append(projectYaml['name'])
    pageTitle.append('WebFu Staging')
    context['pageTitle'] = ' | '.join(pageTitle)

    # Get the footer path & read/parse the footer file.
    footerPath = projectYaml['footer_path']
    footers = yaml.load(devsiteHelper.readFile(footerPath, lang))['footer']
    for item in footers:
        if 'promos' in item:
            context['footerPromos'] = item['promos']
        elif 'linkboxes' in item:
            context['footerLinks'] = item['linkboxes']

    return render('gae/page-landing.html', context)
Esempio n. 7
0
def getPage(requestPath, lang):
    response = None
    title = "Web Fundamentals"
    leftNav = "- No Left Nav Found - "
    toc = "- No TOC Found - "
    banner = devsiteHelper.getAnnouncementBanner(lang)
    template = "gae/article.tpl"
    fileLocations = [
        os.path.join(SOURCE_PATH, lang, requestPath) + ".md",
        os.path.join(SOURCE_PATH, "en", requestPath) + ".md",
        os.path.join(SOURCE_PATH, lang, requestPath) + ".jshtml",
        os.path.join(SOURCE_PATH, "en", requestPath) + ".jshtml",
    ]
    for fileLocation in fileLocations:
        if os.path.isfile(fileLocation):
            content = open(fileLocation, "r").read()
            content = content.decode("utf8")

            # If it's a .jshtml file, just serve it.
            if fileLocation.endswith(".jshtml"):
                return content

            dateUpdated = re.search(r"{# wf_updated_on:[ ]?(.*)[ ]?#}", content)
            if dateUpdated is None:
                logging.warn("Missing wf_updated_on tag.")
                dateUpdated = "Unknown"
            else:
                dateUpdated = dateUpdated.group(1)

            ## Injects markdown includes into the markdown as appropriate
            includes = re.findall(r"^<<.+?\.md>>(?m)", content)
            for includeTag in includes:
                fileName = includeTag.replace("<<", "").replace(">>", "")
                fileName = os.path.join(os.path.dirname(fileLocation), fileName)
                include = devsiteHelper.readFile(fileName, lang)
                if include is None:
                    include = "Warning: Unable to find included markdown file.\n\n"
                content = content.replace(includeTag, include)

            # Remove any comments {# something #} from the markdown
            content = re.sub(r"{#.+?#}", "", content)
            content = re.sub(r"{% comment %}.*?{% endcomment %}(?ms)", "", content)

            # Show warning for unsupported elements
            for tag in UNSUPPORTED_TAGS:
                if re.search(tag, content) is not None:
                    logging.error(" - Unsupported tag: " + tag)
                    replaceWith = '<aside class="warning">Web<strong>Fundamentals</strong>: '
                    replaceWith += "<span>Unsupported tag: <code>" + tag + "</code></span></aside>"
                    content = re.sub(tag, replaceWith, content)

            # Show warning for template tags
            if re.search("{{", content) is not None:
                logging.warn(" - Warning: possible unescaped template tag")

            # Render any DevSite specific tags
            content = devsiteHelper.renderDevSiteContent(content, lang)

            # If it's a markdown file, parse it to HTML
            if fileLocation.endswith(".md"):
                content = re.sub(
                    r"^Note: (.*?)\n^\n(?ms)",
                    r'<aside class="note" markdown="1"><strong>Note:</strong> <span>\1</span></aside>',
                    content,
                )
                content = re.sub(
                    r"^Caution: (.*?)\n^\n(?ms)",
                    r'<aside class="caution" markdown="1"><strong>Caution:</strong> <span>\1</span></aside>',
                    content,
                )
                content = re.sub(
                    r"^Warning: (.*?)\n^\n(?ms)",
                    r'<aside class="warning" markdown="1"><strong>Warning:</strong> <span>\1</span></aside>',
                    content,
                )
                content = re.sub(
                    r"^Key Point: (.*?)\n^\n(?ms)",
                    r'<aside class="key-point" markdown="1"><strong>Key Point:</strong> <span>\1</span></aside>',
                    content,
                )
                content = re.sub(
                    r"^Key Term: (.*?)\n^\n(?ms)",
                    r'<aside class="key-term" markdown="1"><strong>Key Term:</strong> <span>\1</span></aside>',
                    content,
                )
                content = re.sub(
                    r"^Objective: (.*?)\n^\n(?ms)",
                    r'<aside class="objective" markdown="1"><strong>Objective:</strong> <span>\1</span></aside>',
                    content,
                )
                content = re.sub(
                    r"^Success: (.*?)\n^\n(?ms)",
                    r'<aside class="success" markdown="1"><strong>Success:</strong> <span>\1</span></aside>',
                    content,
                )
                content = re.sub(
                    r"^Dogfood: (.*?)\n^\n(?ms)",
                    r'<aside class="dogfood" markdown="1"><strong>Dogfood:</strong> <span>\1</span></aside>',
                    content,
                )

                # Adds a set of markdown extensions available to us on DevSite
                ext = [
                    "markdown.extensions.attr_list",  # Adds support for {: #someid }
                    "markdown.extensions.meta",  # Removes the meta data from the top of the doc
                    "markdown.extensions.toc",  # Generate the TOC for the right side
                    "markdown.extensions.tables",  # Support for Markdown Tables
                    "markdown.extensions.extra",  # Support for markdown='1' in tags
                    "markdown.extensions.def_list",  # Support for definition lists
                ]
                md = markdown.Markdown(extensions=ext)
                content = md.convert(content)

                # Reads the book.yaml file and generate the lefthand nav
                if "book_path" in md.Meta and len(md.Meta["book_path"]) == 1:
                    bookPath = md.Meta["book_path"][0]
                    leftNav = devsiteHelper.getLeftNav(requestPath, bookPath, lang)

                # Checks if the page should be displayed in full width mode
                if "full_width" in md.Meta and len(md.Meta["full_width"]) == 1:
                    fullWidth = md.Meta["full_width"][0]
                    if fullWidth.lower().strip() == "true":
                        template = "gae/home.tpl"

                # Build the table of contents & transform so it fits within DevSite
                toc = md.toc
                toc = toc.strip()
                # Strips the outer wrapper and the page title from the doc
                toc = re.sub(r'<div class="toc">(.*?<ul>){2}(?s)', "", toc)
                toc = re.sub(r"</ul>\s*</li>\s*</ul>\s*</div>(?s)", "", toc)
                # Add appropriate classes
                toc = re.sub(r"<ul>", '<ul class="devsite-page-nav-list">', toc)
                toc = re.sub(r"<a href", '<a class="devsite-nav-title" href', toc)
                toc = re.sub(r"<li>", '<li class="devsite-nav-item">', toc)

            # Replaces <pre> tags with prettyprint enabled tags
            content = re.sub(r"^<pre>(?m)", r'<pre class="prettyprint">', content)

            # Get the page title from the markup.
            titleRO = re.search(r'<h1 class="page-title".*?>(.*?)<\/h1>', content)
            if titleRO:
                title = titleRO.group(1)

            gitHubEditUrl = "https://github.com/google/WebFundamentals/blob/"
            gitHubEditUrl += "master/src/content/"
            gitHubEditUrl += fileLocation.replace(SOURCE_PATH, "")

            gitHubIssueUrl = "https://github.com/google/WebFundamentals/issues/"
            gitHubIssueUrl += "new?title=Feedback for: " + title + " ["
            gitHubIssueUrl += lang + "]&body="
            gitHubIssueUrl += gitHubEditUrl

            # Renders the content into the template
            response = render(
                template,
                {
                    "title": title,
                    "announcementBanner": banner,
                    "gitHubIssueUrl": gitHubIssueUrl,
                    "gitHubEditUrl": gitHubEditUrl,
                    "requestPath": requestPath.replace("index", ""),
                    "leftNav": leftNav,
                    "content": content,
                    "toc": toc,
                    "dateUpdated": dateUpdated,
                    "lang": lang,
                },
            )
            break

    return response
Esempio n. 8
0
def parse(requestPath, fileLocation, content, lang='en'):
  context = {
    'lang': lang,
    'requestPath': requestPath.replace('/index', ''),
    'bodyClass': 'devsite-doc-page',
    'servedFromAppEngine': SERVED_FROM_AE
  }

  ## Injects markdown includes into the markdown as appropriate
  includes = re.findall(r'^<<.+?\.md>>(?m)', content)
  for includeTag in includes:
    fileName = includeTag.replace('<<', '').replace('>>', '')
    fileName = os.path.join(os.path.dirname(fileLocation), fileName)
    include = devsiteHelper.readFile(fileName, lang)
    if include is None:
      include = 'Warning: Unable to find included markdown file.\n\n'
    content = content.replace(includeTag, include)

  # Remove any comments {# something #}
  content = re.sub(r'{#.+?#}', '', content)
  content = re.sub(r'{% comment %}.*?{% endcomment %}(?ms)', '', content)

  # Remove any markdown=1 since it's not supported
  content = re.sub(r'markdown=[\'\"]?1[\'\"]?', '', content)

  # Render any DevSite specific tags
  content = devsiteHelper.renderDevSiteContent(content, lang)

  # Turn Callouts into the appropriate HTML elements
  content = re.sub(r'^Note: (.*?)\n^\n(?ms)', r'<aside class="note" markdown="1"><strong>Note:</strong> <span>\1</span></aside>', content)
  content = re.sub(r'^Caution: (.*?)\n^\n(?ms)', r'<aside class="caution" markdown="1"><strong>Caution:</strong> <span>\1</span></aside>', content)
  content = re.sub(r'^Warning: (.*?)\n^\n(?ms)', r'<aside class="warning" markdown="1"><strong>Warning:</strong> <span>\1</span></aside>', content)
  content = re.sub(r'^Key Point: (.*?)\n^\n(?ms)', r'<aside class="key-point" markdown="1"><strong>Key Point:</strong> <span>\1</span></aside>', content)
  content = re.sub(r'^Key Term: (.*?)\n^\n(?ms)', r'<aside class="key-term" markdown="1"><strong>Key Term:</strong> <span>\1</span></aside>', content)
  content = re.sub(r'^Objective: (.*?)\n^\n(?ms)', r'<aside class="objective" markdown="1"><strong>Objective:</strong> <span>\1</span></aside>', content)
  content = re.sub(r'^Success: (.*?)\n^\n(?ms)', r'<aside class="success" markdown="1"><strong>Success:</strong> <span>\1</span></aside>', content)
  content = re.sub(r'^Dogfood: (.*?)\n^\n(?ms)', r'<aside class="dogfood" markdown="1"><strong>Dogfood:</strong> <span>\1</span></aside>', content)

  # Adds a set of markdown extensions available to us on DevSite
  ext = [
    'markdown.extensions.attr_list', # Adds support for {: #someid }
    'markdown.extensions.meta', # Removes the meta data from the top of the doc
    'markdown.extensions.toc', # Generate the TOC for the right side
    'markdown.extensions.tables', # Support for Markdown Tables
    'markdown.extensions.def_list', # Support for definition lists
    'markdown.extensions.extra' #
  ]
  md = markdown.Markdown(extensions=ext)
  content = md.convert(content)

  # Replaces <pre> tags with prettyprint enabled tags
  content = re.sub(r'^<pre>(?m)', r'<pre class="prettyprint devsite-code-highlight">', content)
  # Adds code highlighting support, which requires devsite-code-highlight
  content = re.sub(r'^<pre class="prettyprint">(?m)', r'<pre class="prettyprint devsite-code-highlight">', content)

  # Save the content
  context['content'] = content

  # Get the project_path and read/parse the project file.
  projectPath = md.Meta['project_path'][0]
  projectYaml = yaml.load(devsiteHelper.readFile(projectPath, lang))
  context['projectYaml'] = projectYaml

  # Read the parent project.yaml file if applicable
  parentProjectYaml = None
  if 'parent_project_metadata_path' in projectYaml:
    parentprojectPath = projectYaml['parent_project_metadata_path']
    parentProjectYaml = yaml.load(devsiteHelper.readFile(parentprojectPath, lang))

  # Reads the book.yaml file and generate the lefthand nav
  bookPath = md.Meta['book_path'][0]
  bookYaml = devsiteHelper.parseBookYaml(bookPath, lang)
  context['bookYaml'] = devsiteHelper.expandBook(bookYaml)
  # context['lowerTabs'] = devsiteHelper.getLowerTabs(bookYaml)
  context['renderedLeftNav'] = devsiteHelper.getLeftNav(requestPath, bookYaml)

  lowerTabs = devsiteHelper.getLowerTabs(bookYaml)
  context['lowerTabs'] = lowerTabs

  # Get the logo row (TOP ROW) icon
  context['logoRowIcon'] = projectYaml['icon']['path']

  # Get the logo row (TOP ROW) title
  if parentProjectYaml:
    context['logoRowTitle'] = parentProjectYaml['name']
  else:
    context['logoRowTitle'] = projectYaml['name']

  # Get the header title & description
  context['headerTitle'] = projectYaml['name']
  # headerDescription is rarely shown, hiding temporarily
  # context['headerDescription'] = projectYaml['description']

  # Get the page title
  pageTitle = []
  titleRO = re.search(r'<h1 class="page-title".*?>(.*?)<\/h1>', content)
  if titleRO:
    pageTitle.append(titleRO.group(1))
  pageTitle.append(projectYaml['name'])
  pageTitle.append('WebFu Staging')
  context['pageTitle'] = ' | '.join(pageTitle)

  # Get the footer path & read/parse the footer file.
  footerPath = projectYaml['footer_path']
  footers = yaml.load(devsiteHelper.readFile(footerPath, lang))['footer']
  for item in footers:
    if 'promos' in item:
      context['footerPromos'] = item['promos']
    elif 'linkboxes' in item:
      context['footerLinks'] = item['linkboxes']

  if 'full_width' in md.Meta and len(md.Meta['full_width']) == 1:
    context['fullWidth'] = True

  # Build the table of contents & transform so it fits within DevSite
  toc = md.toc
  toc = toc.strip()
  # Strips the outer wrapper and the page title from the doc
  toc = re.sub(r'<div class="toc">(.*?<ul>){2}(?s)', '', toc)
  toc = re.sub(r'</ul>\s*</li>\s*</ul>\s*</div>(?s)', '', toc)
  # Add appropriate classes
  toc = re.sub(r'<ul>', '<ul class="devsite-page-nav-list">', toc)
  toc = re.sub(r'<a href', '<a class="devsite-nav-title" href', toc)
  toc = re.sub(r'<li>', '<li class="devsite-nav-item">', toc)
  context['renderedTOC'] = toc;

  gitHubEditUrl = 'https://github.com/google/WebFundamentals/blob/'
  gitHubEditUrl += 'master/src/content/'
  gitHubEditUrl += fileLocation.replace(SOURCE_PATH, '')
  context['gitHubEditUrl'] = gitHubEditUrl

  gitHubIssueUrl = 'https://github.com/google/WebFundamentals/issues/'
  gitHubIssueUrl += 'new?title=Feedback for: ' + context['pageTitle'] + ' ['
  gitHubIssueUrl += lang + ']&body='
  gitHubIssueUrl += gitHubEditUrl
  context['gitHubIssueUrl'] = gitHubIssueUrl

  return render('gae/page-article.html', context)