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

我有一个项目和几个人在一起,我们有一个README.md文件,在GitHub页面上显示了一堆GitHub README.md Markdown。 我们还build立了一个GitHub页面分支,它在我们的GitHub组织的子域下托pipe,并且当我们创build页面时,使用自动页面生成器简单地加载到我们的README.md文件中。 但是,我注意到,当我更新我们的README.md文件时,它不会更新项目页面。 相反,我们必须到GitHub设置选项卡并重新创build项目页面,当我们这样做时重新加载README.md文件。

另外,阅读了GitHub项目目录页上的文档文件之间的相对链接工作。 我非常喜欢降价,因为它可以节省大量的时间,无需手动为我们的文档编写所有的HTML。 然而,我想要的是能够有一个README.md文件,它能够包含相关链接到位于docs/*.md README.md其他文档文件。 我希望有一个简单的解决scheme,以便我的其他文档文件也可能包含在我的gh页面分支,并承载在我的GitHub页面子域,并呈现和/或主题。

换句话说,我的问题是:

  • 有没有办法让我的README.md文件自动更新我的Github页面子域?
    • [编辑]:如果使用自动页面生成器,否似乎是答案。 您必须进入repo的设置页面并在每次更改时重新加载以便更新。
  • 有没有办法,我可以有我的相关链接到我的文档上我的README.md文件工作在我的Github页面,也许我同步我的/docs/*.md到我的Github页面,并以某种方式渲染和/或主题呢?
    • [编辑]:从我写这个问题以来,我所学到的,似乎这只能在GitHub页面上通过使用像ruby gem Jekyll这样的静态站点生成器 ,以及可能被GitHub支持webhooks的一些用途在下面的评论。 我正在尝试find一个最佳的解决scheme。
  • 更好的是,有没有更简单的方法,我可以做到这一点,也许只有一个我的README.md和文档的副本,在gh页面和我的主分支上使用,使一切都变得容易?
    • [编辑]:看来这个几乎肯定是一个不。 我正在考虑在GitHub中构build一些内容的可能性。 似乎对这种事情的更好的支持可能会在未来被构build到GitHub页面中,或者至less我绝对希望这样做。

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

  1. git checkout gh-pages
  2. mkdir _layouts
  3. mv index.html _layouts
  4. git checkout master -- README.md
  5. mv README.md index.md
  6. 将以下文本添加到index.md
 --- layout: index --- 

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

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

  2. find项目页面主题的CSS。 对我来说,这是一个如下的线:

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

    这需要更改为

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

  3. 存储在您的网站上的任何其他资源将在此布局中使用,还需要以{{ site.path }}为前缀。

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

创build了包含以下内容的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 

编辑:我更新了上述脚本的README.md文件和docs/*的降价都使用相同的布局文件。 这是一个比以前更好的设置。 这个脚本放在你的.git/hooks/目录下。 bash必须在你的路上。

使用以下命令创build文件_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]); }); }); 

编辑:我改变了上面的代码在我的仓库中,这是一个快速和肮脏的方式来做到这一点,但它不会正常工作,如果你知道我的意思..例如,markdown文件company.mdata.md不会被正确处理。 为了解决这个问题,我把它更新到了下面的脚本,它更仔细地检查了href并删除了扩展名(如果find的话)。 我也使脚本更通用,允许通过更改extvariables来删除其他扩展。 这里是代码:

 $(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中设置了一个示例回购,如果您想了解所有这些工作是如何协同工作的,请在这里有一个项目页面

我的解决scheme与Github页面同步README的问题略有不同。 可以使用Github API来返回一个以HTML格式呈现的Markdown文件,而不是使用单独的JavaScript Markdown引擎。

  1. https://api.github.com/repos/<owner>/<repo>/contents/README.md获取README.md
  2. 解码Base64响应: window.atob( JSON.parse( blob ).content );
  3. 在JSON正文中将解码的READMEhttps://api.github.com/markdown

      { "text": "<README>", "mode": "markdown", "context": "<owner>/<repo>" } 
  4. 将呈现的HTML插入到DOM元素中,就像Brad Rhodes所做的那样。

这种方法的两个注意事项:

  1. 执行两个串行请求会减慢页面加载速度。
  2. 访问Github API时可能遇到速率限制。

对于加载时间不重要(〜1-2秒)的低stream量页面,则上述方法运行良好。

我有几个想法来共享您的文档网站和主github回购之间的单个自述文件:

  1. 您只能使用包含您的代码和jekyll文档站点的单个gh页面分支。 您的存储库可能会有点混乱,您需要在自述文件的顶部放置一个YAML标头。 它几乎支持相对链接。 问题是,如果你想要jekyll呈现你的降价,它会给它一个.html扩展名。 也许有一种方法来configuration这个。 这里有一个例子,我扔在一起,看看它是否工作。

  2. 您可以在文档站点中使用AJAX调用,从主分支中读取自述文件,然后使用JavaScript Markdown渲染器进行渲染 。 这将需要一些时间来加载,它不会支持相关的链接,而无需你写一些聪明的Javascript。 实施比理念1更多的工作。

另一种考虑的方法是build立一个预先提交的钩子来build立相关的页面。 我在我的一个仓库中这样做。 你可能不得不放弃自动页面生成器,而只是自己推送到gh-pages分支,而且像Nathan所build议的那样 ,把你的文档转换成HTML或Jekyll站点。

在这个库中, 我像这样推动 gh-pages保持与master相同。 还有很多其他方法可以做到这一点。 虽然这可能不适合你的情况(你可能不希望它们是相同的)。

无论如何,我在这个问题上提供了一个赏金的原因是因为我希望有一个更好的工作stream程。 这种方法是令人费解和僵化的,它需要每个人保持同步。

另一种方法,我已经得到相当成功的工作是使用Ajax来获取文档使用Github API和JavaScript降价引擎来呈现HTML(也由Nathanbuild议)。

  1. 使用Github API和JSONP从Github获取文档
  2. 解码来自Github API的响应中的base64内容
  3. 使用JavaScript降价引擎呈现降价
  4. 显示呈现的HTML

内森对performanceperformance出一些担忧,但以我的经验来看,这似乎立即加载,所以我不认为这实际上是一个问题。

好处是它易于安装,即使您只是直接在github上的浏览器中编辑降价,它也会一直更新您的文档。

我在http://bradrhodes.github.io/GithubDocSync/上的Github页面上设置了一个例子来显示它的工作。;

您可以使用DocumentUp来呈现您的README.md。

Nathan和Brand Rhodes描述的方法的另一种可能性是使用一个很好的工具:由Rico Sta创build的FlatDoc 。 克鲁兹。

FlatDoc将通过ajax加载文档(README.md或任何其他降价文件),parsing并显示所有的好东西,甚至边栏菜单导航!

它已经在其api中构build了一个辅助方法来从GitHub repo master加载文件(但也可以从网上加载其他任何地方)。

说明

首先将下面的html模板复制到你的gh-pages分支的index.html中。 继续:

  • 用你的GitHub用户名replace“USER”
  • 用你的GitHub仓库名称replace“REPO”
  • 用您的项目名称replace“您的项目”

在文件中。 在浏览器中进行本地化尝试。 然后提交并推送更改。 现在你的github页面将会随你的master分支中的README.md文件一起更新。

如果默认的主题不适合你,你可以用你自己的CSS重新devise它。

我也想编辑主文档中的文档并在gh-pages中发布 – 我喜欢将文档与源代码保持一致,这似乎是最好的方法。 这是我正在进行的工作,但是我把Cory的脚本作为起点,只要有一个带有_layouts (即一个jekyll站点)的gh-pages分支,就可以将其扩展一些,使其成为开箱即用的工具。 它转换反向风格的击剑(代码块),在github源浏览,但不是在gh页面中很好地工作。 我使用一个包含项目README.md这样我就可以添加一个头文件和一些其他的装饰。 这个版本还处理所有名为“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 } } } 

从原来的另一个变化是,它在所有页面中设置一个variablespage.home 。 这可以用来定位根目录的相对path,所以它可以用来定位像CSS这样的静态资源。 在_layouts/.default.html我有:

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

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

我最近做了一个包gh-pages-generator来解决这个问题 – 它使用多个MD文件和configuration文件生成多页面的网站。

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

我在这里和这里使用它。

这并不难 ,两个复制和粘贴到terminal,你都设置。

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

在github上查看如何设置一个超级准系统的Jekyll站点是值得的(这只是两个文件!

设置

您可以复制这两个文件,并通过运行这个一次性设置将整个代码块和pase复制到terminal中 )使您的页面与当前的自述文件一起进行:

 # 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 

自动化

然后,我们只需要在每次推送之前自动完成从mastergh-pages分支的所有更改的任务。 我们可以通过运行这个脚本来做到这一点( 你可以复制并粘贴到terminal中

 $(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 

它会创build一个push hook,每次运行git push时候都会把master分支上的所有更改复制到gh-pages

而已。 完成。