首页 文章

如何将文档与Github页面同步?

提问于
浏览
78

我有一个项目和几个人一起,我们有一个带有一堆GitHub Flavored Markdown的 README.md 文件,它在我们的GitHub页面上呈现 . 我们还设置了一个GitHub Pages分支,它在我们的GitHub组织的子域下托管,并在我们创建页面时使用Automatic Page Generator简单地加载到我们的 README.md 文件中 . 但是,我注意到当我更新 README.md 文件时,它不会更新项目页面 . 相反,我们必须转到GitHub设置选项卡并重新创建项目页面,在我们这样做时重新加载 README.md 文件 .

另外,在阅读了关于GitHub项目目录页面上的文档文件之间的relative linking之后 . 我非常喜欢降价,因为它为我们的文档手动编写所有HTML节省了大量时间 . 但我想要的是能够拥有一个 README.md 文件,该文件能够包含位于 docs/*.md 的其他文档文件的相对链接 . 我希望有一个简单的解决方案,以便我的其他文档文件也可以包含在我的gh-pages分支中,并在我的GitHub Pages子域下托管并呈现和/或主题化 .

换句话说,我的问题是:

  • 有没有办法让我的README.md文件在我的Github页子域上自动更新?

  • [ EDIT ] : 如果使用自动页面生成器,似乎没有答案 . 您必须转到repo的设置页面,并在每次更改时重新加载它以便更新它 .

  • 有没有办法可以将我的README.md文件上的文档的相关链接放在我的Github页面上,也许我会以某种方式将我的 /docs/*.md 同步到我的Github页面并以某种方式呈现和/或主题化它们?

  • [ EDIT ] : 从我写这个问题以来我学到的东西似乎只能通过使用像ruby gem Jekyll这样的static site generator以及下面评论中提到的webhooks supported by GitHub的一些用途在GitHub页面上实现 . 我正在尝试寻找最佳解决方案 .

  • 更好的是,有没有更简单的方法可以做到这一点,也许只有一份我的README.md和文档,用于gh-pages和我的主分支,并使一切最简单?

  • [ EDIT ] : 看来这个几乎肯定是不行的 . 我正在考虑GitHub中内置的东西的可能性 . 似乎未来可能会在GitHub页面中构建对此类事物的更好支持,或者至少我绝对希望它会成为 .

10 回答

  • 3

    我将发布一个我设置的解决方案,利用GitHub Pages使用Jekyll已经使用自动页面生成器的事实 .

    • git checkout gh-pages

    • mkdir _layouts

    • mv index.html _layouts

    • git checkout master -- README.md

    • mv README.md index.md

    • 将以下文字添加到 index.md

    ---
    layout: index
    ---
    

    您还需要打开 index.html 文件并进行以下更改:

    • README.md 文件中的markdown中删除呈现的HTML . 这通常在 <section><article> 标签之间 . 将此HTML替换为文本 {{ content }} ,这将允许我们将此文件用作jekyll . 我们应用布局的文件将放置在内容标记所在的位置 .

    • 找到项目页面主题的CSS . 对我来说,这是一个如下所示的行:

    <link rel='stylesheet' href='stylesheets/stylesheet.css' />

    这需要改为

    <link rel='stylesheet' href='{{ site.path }}/stylesheets/stylesheet.css' />

    • 您网站上存储的将在此布局中使用的任何其他资产也需要以 {{ site.path }} 作为前缀 .

    通过这样做,Jekyll将markdown文件呈现为 _layouts 目录中 index.html 布局的内容 . 为了使这个过程不仅自动化README.md文件,而且还自动化您的主分支中的其他文档,我采取了以下步骤:

    创建名为 post-commit 的文件,其中包含以下内容:

    #!/bin/bash
    ###
    ### The following block runs after commit to "master" branch
    ###
    if [ `git rev-parse --abbrev-ref HEAD` == "master" ]; then
    
        # Layout prefix is prepended to each markdown file synced
        ###################################################################
        LAYOUT_PREFIX='---\r\nlayout: index\r\n---\r\n\r\n'
    
        # Switch to gh-pages branch to sync it with master
        ###################################################################
        git checkout gh-pages
    
        # Sync the README.md in master to index.md adding jekyll header
        ###################################################################
        git checkout master -- README.md
        echo -e $LAYOUT_PREFIX > index.md
        cat README.md >> index.md
        rm README.md
        git add index.md
        git commit -a -m "Sync README.md in master branch to index.md in gh-pages"
    
        # Sync the markdown files in the docs/* directory
        ###################################################################
        git checkout master -- docs
        FILES=docs/*
        for file in $FILES
        do
            echo -e $LAYOUT_PREFIX | cat - "$file" > temp && mv temp "$file"
        done
    
        git add docs
        git commit -a -m "Sync docs from master branch to docs gh-pages directory"
    
        # Uncomment the following push if you want to auto push to
        # the gh-pages branch whenever you commit to master locally.
        # This is a little extreme. Use with care!
        ###################################################################
        # git push origin gh-pages
    
        # Finally, switch back to the master branch and exit block
        git checkout master
    fi
    

    EDIT: 我为 README.md 文件和 docs/* 中的markdown更新了上述脚本,两者都使用相同的布局文件 . 这是一个比我以前更好的设置 . 此脚本位于 .git/hooks/ 目录中 . bash必须在你的道路上 .

    使用以下内容创建文件 _config.yml

    markdown: redcarpet
    path: http://username.github.io/reponame
    

    上面的脚本还同步 master 分支的 docs/* 目录中的markdown文件,以便它们也可以在GitHub Pages站点上查看 . 如果包含以下jQuery,则相对链接到这些文档函数以从 gh-pages 分支上的锚点剥离 .md 扩展名 . 您可以将以下脚本添加到 _layouts 目录中的 index.html

    $(document).on('ready', function () {
        $('a').each(function (i, e) {
            var href = e.href;
            if (href.search('.md') > 0)
                $(this).attr('href', href.split('.md')[0]);
        });
    });
    

    EDIT: 我在我的存储库中更改了上面的代码,这是一种快速而又脏的方法,但是如果你知道我的意思,它在所有情况下都无法正常工作 . 例如,markdown文件 company.mdata.md 将不会被处理正确 . 为了解决这个问题,我将其更新为以下脚本,该脚本会更仔细地检出href并删除扩展名(如果找到) . 我还使脚本更通用,允许它通过更改 ext 变量来删除其他扩展 . 这是代码:

    $(function () {
        $('a').each(function () {
            var ext = '.md';
            var href = $(this).attr('href');
            var position = href.length - ext.length;
            if (href.substring(position) === ext)
                $(this).attr('href', href.substring(0, position));
        });
    });
    

    我在CoryG89/docsync设置了一个示例仓库,它有一个project page here,如果你想看看它们是如何协同工作的 .

  • 1

    我对README与Github页面同步问题的解决方案与上述略有不同 . 可以使用Github API返回呈现为HTML的Markdown文件,而不是使用单独的JavaScript Markdown引擎 .

    • https://api.github.com/repos/<owner>/<repo>/contents/README.md 获取 README.md .

    • 解码Base64响应: window.atob( JSON.parse( blob ).content );

    • 将已解码的 README 发布到JSON正文中的 https://api.github.com/markdown

    {
       "text": "<README>",
       "mode": "markdown",
       "context": "<owner>/<repo>"
     }
    
    • 将呈现的HTML插入到DOM元素中,如Brad Rhodes所示 .

    这种方法有两点需要注意:

    • 执行两个串行请求会减慢页面加载速度 .

    • 访问Github API时可能会遇到速率限制 .

    对于负载时间不重要(~1-2秒)的低流量页面,上述方法运行良好 .

  • 3

    我有几个想法,在您的文档站点和主github仓库之间共享一个自述文件:

    • 您只能使用包含代码和jekyll文档站点的单个gh-pages分支 . 您的存储库可能会变得有点混乱,您需要在自述文件的顶部放置一个YAML标头 . 它几乎支持相对链接 . 问题是,如果你想让jekyll渲染你的降价,它会给它一个.html扩展名 . 也许有一种方法可以配置它 . Here's an example I threw together to see if it works.

    • 您可以在文档站点中使用AJAX调用从主分支读取自述文件,然后使用Javascript Markdown renderer进行渲染 . 这需要更长的时间来加载,如果没有你编写一些聪明的Javascript,它将不支持相对链接 . 实现比创意1更多的工作 .

  • 0

    另一个需要考虑的方法是设置一个构建相关页面的pre-commit hook . 我在one of my repositories这样做 . 你可能不得不放弃自动页面生成器,只是自己推送到 gh-pages 分支,以及做一些想要把你的文档变成HTML或Jekyll网站的东西Nathan suggests .

    在该存储库I push like this中保持 gh-pagesmaster 相同 . 还有很多other ways也是这样做的 . 这可能不适合您的情况(您可能不希望它们相同) .

    无论如何,我在这个问题上提供赏金的原因是因为我希望有人有更好的工作流程 . 这种方法有点复杂和不灵活,它需要每个人保持他们的钩子同步 .

  • 2

    您可以使用DocumentUp呈现README.md .

  • 5

    我已经非常成功地工作的另一种方法是使用Ajax使用Github API和Javascript markdown引擎来获取文档以呈现HTML(Nathan也建议) .

    • 使用Github API和JSONP从Github获取文档

    • 解码来自Github API的响应中的base64内容

    • 使用javascript markdown引擎渲染降价

    • 显示渲染的html

    Nathan表达了对性能的一些担忧,但根据我的经验,它似乎立即加载,所以我不认为这实际上是一个问题 .

    优点是它易于设置,即使您只是直接在github上的浏览器中编辑markdown,它也将始终更新您的文档 .

    我在http://bradrhodes.github.io/GithubDocSync/的Github页面上设置了一个示例,以显示它正常工作 .

  • 2

    Nathan和Brand Rhodes描述的方法的另一种可能性是使用一个伟大的工具:FlatDoc由Rico Sta创建 . 克鲁兹 .

    FlatDoc将通过ajax加载文档(README.md或任何其他markdown文件),解析它并显示所有好东西,甚至侧边栏菜单进行导航!

    它在api中构建了一个辅助方法,用于从GitHub repo master加载文件(但也可以从Web上的任何其他地方加载) .

    Instructions 首先将以下html template复制到gh-pages分支的index.html中 . 继续:

    • 用您的GitHub用户名替换"USER"

    • 用您的GitHub仓库名称替换"REPO"

    • 用项目名称替换"Your Project"

    在文件中 . 在浏览器中本地试用 . 然后提交并推送更改 . 现在,您的github页面将始终使用主分支中的README.md文件进行更新 .

    如果默认主题不适合您,您可以使用自己的CSS重新设置样式 .

  • 36

    我还想在master中编辑文档并在gh-pages中发布 - 我喜欢让文档与源代码保持同步,这似乎是最好的方法 . 这对我来说正在进行中,但是我把Cory's script作为一个起点并进行了扩展,只要有一个带有 _layouts (即一个jekyll网站)的gh-pages分支就可以开箱即用 . 它转换反引号样式的防护(对于代码块),它在github源代码浏览中很好地工作,但不在gh-pages中 . 我使用带有项目 README.md 的include的 index.md ,所以我可以添加 Headers 和其他一些装饰 . 这个版本还处理任何名为"docs"的嵌套目录中的文档,我觉得这在有多个模块的项目中很有用(不是git子模块,只是子目录):

    .git/hooks/post-commit

    #!/bin/bash
    ###
    ### The following block runs after commit to "master" branch
    ###
    if [ `git rev-parse --abbrev-ref HEAD` == "master" ]; then
    
        # function to convert a plain .md file to one that renders nicely in gh-pages
        function convert {
            # sed - convert links with *.md to *.html (assumed relative links in local pages)
            # awk - convert backtick fencing to highlights (script from bottom of file)
            sed -e 's/(\(.*\)\.md)/(\1.html)/g' "$1" | awk -f <(sed -e '0,/^#!.*awk/d' $0) > _temp && mv _temp "$1"
        } 
    
        if ! git show-ref --verify --quiet refs/heads/gh-pages; then
            echo "No gh-pages, so not syncing"
            exit 0
        fi
    
        # Switch to gh-pages branch to sync it with master
        ###################################################################
        git checkout gh-pages
    
        mkdir -p _includes
    
        # Sync the README.md in master to index.md adding jekyll header
        ###################################################################
        git checkout master -- README.md
        if [ -f README.md ]; then
            cp README.md _includes/
            convert _includes/README.md
            git add README.md
            git add _includes/README.md
        fi
    
        # Generate index if there isn't one already
        ###################################################################
        if [ ! -f index.md ]; then
            echo -e '---\ntitle: Docs\nlayout: default\n---\n\n{% include README.md %}' > index.md
            git add index.md
        fi
    
        # Generate a header if there isn't one already
        ###################################################################
        if [ ! -f _includes/header.txt ]; then
            echo -e '---\ntitle: Docs\nlayout: default\nhome: \n---\n\n' > _includes/header.txt
            git add _includes/header.txt
        fi
    
        # Sync the markdown files in all docs/* directories
        ###################################################################
        for file in `git ls-tree -r --name-only master | grep 'docs/.*\.md'`
        do
            git checkout master -- "$file"
            dir=`echo ${file%/*} | sed -e "s,[^/]*,..,g"`
            cat _includes/header.txt | sed -e "s,^home: .*$,home: ${dir}/," > _temp
            cat "$file" >> _temp && mv _temp "$file"
            convert "$file"
            git add "$file"
        done
    
        git commit -a -m "Sync docs from master branch to docs gh-pages directory"
    
        # Uncomment the following push if you want to auto push to
        # the gh-pages branch whenever you commit to master locally.
        # This is a little extreme. Use with care!
        ###################################################################
        # git push origin gh-pages
    
        # Finally, switch back to the master branch and exit block
        git checkout master
    fi
    
    exit $?
    
    #!/usr/bin/awk
    {
       # Replace backtick fencing (renders well when browsing github) with jekyll directives
       if (/```/) {
          IN = IN?0:1 # Are we already in a fenced section? Toggle.
          if (IN) { # If we are starting a fenced section
             if (/```\s*$/) {
               $0 = $0"text" # empty language is OK for backticks but not for jekyll
             }
             gsub(/```/, "{% highlight ")
             print $0" %}"
          } else { # ending a fenced section
            print "{% endhighlight %}" 
          }
        } else { # not a fencing line
          if (IN) { # but in a fenced section, so add indent to make sure code is rendered with <pre>
            print "    "$0
          } else {
            print
          }
        }
    }
    

    与原始版本的另一个变体是它在所有页面中设置变量 page.home . 这可用于定位根耐火材料的相对路径,因此可用于定位静态资源,如css . 在 _layouts/.default.html 我有:

    <link rel="stylesheet" href="{{ page.home }}css/main.css">
    

    通过这种方式,我可以编辑css,在本地构建jekyll站点,并在浏览器中查看结果,而无需等待github在服务器上构建它 .

  • 0

    我最近创建了一个包gh-pages-generator来解决这个问题 - 它使用多个MD文件和配置文件生成多页面站点 .

    它正确更新页面之间的所有链接 . 使其成为CI的一部分以将更改提交回gh-pages分支相对容易 .

    我正在使用herehere .

  • 3

    It's not hard ,两个复制并粘贴到终端中,你们都已经设置好了 .

    Jekyll 允许您导入markdown文件,然后将它们转换为HTML . 诀窍是使用 {% include_relative README.md %}README.md 导入到 index.md 文件中 . 以下是我们如何做到这一点:

    值得查看how to setup a super barebones Jekyll site on github(它只是 two files!

    设置

    您可以复制这两个文件,并通过运行此 one time setup (将整个代码块和pase复制到终端)将页面与当前自述文件一起使用:

    # Copy our two files to the gh-pages branch
    git checkout -b gh-pages &&
    wget https://raw.githubusercontent.com/lazamar/barebones-jekyll-project-readme/master/_config.yml &&
    wget https://raw.githubusercontent.com/lazamar/barebones-jekyll-project-readme/master/index.md &&
    #
    # Commit and publish our page on github
    git add -A && git commit -m "Create project github page" &&
    git push --set-upstream origin gh-pages |
    #
    git checkout master # go back to master branch
    

    自动化

    然后我们只需要在每次推送之前自动执行将所有更改从 master 复制到 gh-pages 分支的任务 . 我们可以通过运行此脚本来做到这一点(您可以将其复制并粘贴到终端中)

    $(cat > .git/hooks/pre-push << EOF
    #!/bin/sh
    we_are_in_gh_pages="\$(git branch | grep -G "* gh-pages")"
    
    if [ ! "\$we_are_in_gh_pages" ];
      then
        git checkout gh-pages &&
        git rebase master &&
        git push -f &&
        git checkout master # go back to master branch
    fi
    EOF
    ) && chmod 775 .git/hooks/pre-push
    

    它将创建一个push hook,每次运行 git push 时,都会将 master 分支中的所有更改复制到 gh-pages .

    That's it. Done.

相关问题