diff --git a/.bookignore b/.bookignore new file mode 100644 index 0000000..0d4bd2f --- /dev/null +++ b/.bookignore @@ -0,0 +1 @@ +# only for gitbook diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..967b232 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,30 @@ +# Copyright 2017 . All rights reserved. +# Use of this source code is governed by a Apache +# license that can be found in the LICENSE file. + +# http://editorconfig.org/ + +root = true + +# Unix-style newlines with a newline ending every file +[*] +charset = utf-8 +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = false + +[*] +indent_style = tab + +[*.{go,proto}] +charset = utf-8 +indent_style = tab + +# Matches the exact files either package.json or .travis.yml +[{package.json,.travis.yml}] +indent_style = space +indent_size = 2 + +[*.yaml] +indent_style = space +indent_size = 2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..68c338f --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +# Node rules: +## Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +## Dependency directory +## Commenting this out is preferred by some people, see +## https://docs.npmjs.com/misc/faq#should-i-check-my-node_modules-folder-into-git +node_modules + +# Book build output +_book + +# eBook build output +*.epub +*.mobi +*.pdf + +*.o +*.obj +*.exe + +# macOS +.DS_Store + +*.a +*.lib +*.so +*.dll +*.obj +*.o +a.out + +.oracle_jre_usage + +# Delve +debug diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a67dc31 --- /dev/null +++ b/Makefile @@ -0,0 +1,48 @@ +# Copyright 2016 . All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +# +# fix gitbook build error on macOS(node@8.x and gitbook@2.6.7) +# +# gitbook fetch 3.2.3 +# gitbook build --gitbook=3.2.3 +# +# https://github.com/GitbookIO/gitbook/issues/1774 +# https://github.com/GitbookIO/gitbook-cli/blob/master/README.md +# + +default: + gitbook build + +macos: + gitbook build --gitbook=3.2.3 + +macos-pdf: + mv preface.md preface-bak.md && mv preface-pdf.md preface.md + gitbook pdf --gitbook=3.2.3 + mv preface.md preface-pdf.md && mv preface-bak.md preface.md + +server: + go run server.go + +cover: + convert -resize 1800x2360! cover.png cover.jpg + convert -resize 200x262! cover.png cover_small.jpg + + +# https://chai2010.cn/go2-book +deploy: + -rm -rf _book + gitbook build + + cd _book && \ + git init && \ + git add . && \ + git commit -m "Update github pages" && \ + git push --force --quiet "https://github.com/chai2010/go2-book.git" master:gh-pages + + @echo deploy done + +clean: + -rm -rf _book diff --git a/README.md b/README.md index 948980c..d4aa724 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,17 @@ -# go2-book -Go2编程指南 +# Go2编程指南 + +本书重点讲解Go2新特性,以及Go1教程中较少涉及的特性。本书适合对Go语言有一定基础的用户学习。 + +![](cover.png) + +- 作者:柴树杉,Github [@chai2010](https://github.com/chai2010),Twitter [@chaishushan](https://twitter.com/chaishushan) + + +## 在线阅读 + +- [SUMMARY.md](SUMMARY.md) + +## 版权声明 + +自有版权,严禁任何使用。 + diff --git a/SUMMARY.md b/SUMMARY.md new file mode 100644 index 0000000..f2f3eba --- /dev/null +++ b/SUMMARY.md @@ -0,0 +1,3 @@ +# 目录 + +* [第1章 语法糖变迁](ch1/readme.md) diff --git a/book.json b/book.json new file mode 100644 index 0000000..db64cb0 --- /dev/null +++ b/book.json @@ -0,0 +1,20 @@ +{ + "gitbook": "3.x", + "title": "Go2编程指南", + "description": "Go2编程指南", + "language": "zh-hans", + + "structure": { + "readme": "preface.md" + }, + + "pluginsConfig": { + "theme-default": { + "showLevel": false + } + }, + + "plugins": [ + "-search" + ] +} diff --git a/ch1/readme.md b/ch1/readme.md new file mode 100644 index 0000000..e69de29 diff --git a/cover.jpg b/cover.jpg new file mode 100644 index 0000000..3106799 Binary files /dev/null and b/cover.jpg differ diff --git a/cover.png b/cover.png new file mode 100644 index 0000000..20e1ae8 Binary files /dev/null and b/cover.png differ diff --git a/cover_small.jpg b/cover_small.jpg new file mode 100644 index 0000000..d08a668 Binary files /dev/null and b/cover_small.jpg differ diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..5cc499b --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +// Copyright 2018 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +module github.com/chai2010/go2-book diff --git a/preface.md b/preface.md new file mode 100644 index 0000000..04f9dfd --- /dev/null +++ b/preface.md @@ -0,0 +1,18 @@ +# Go2编程指南 + +本书重点讲解Go2新特性,以及Go1教程中较少涉及的特性。本书适合对Go语言有一定基础的用户学习。 + +![](cover.png) + +- 作者:柴树杉,Github [@chai2010](https://github.com/chai2010),Twitter [@chaishushan](https://twitter.com/chaishushan) + + +## 版权声明 + +自有版权,严禁任何使用。 + +----- + +# 前言 + +TODO diff --git a/server.go b/server.go new file mode 100644 index 0000000..0bf15bf --- /dev/null +++ b/server.go @@ -0,0 +1,142 @@ +// Copyright 2016 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +package main + +import ( + "flag" + "log" + "net" + "net/http" + "os/exec" + "runtime" + "time" +) + +var ( + flagRootDir = flag.String("dir", ".", "root dir") + flagHttpAddr = flag.String("http", ":8080", "HTTP service address") + flagNoCache = flag.Bool("no-cache", true, "disable browser cache") + flagOpenBrowser = flag.Bool("openbrowser", true, "open browser automatically") +) + +func main() { + flag.Parse() + + host, port, err := net.SplitHostPort(*flagHttpAddr) + if err != nil { + log.Fatal(err) + } + + if host == "" { + host = getLocalIP() + } + httpAddr := host + ":" + port + url := "http://" + httpAddr + "/_book" + + go func() { + log.Printf("dir: %s\n", *flagRootDir) + + if waitServer(url) && *flagOpenBrowser && startBrowser(url) { + log.Printf("A browser window should open. If not, please visit %s", url) + } else { + log.Printf("Please open your web browser and visit %s", url) + } + log.Printf("Hit CTRL-C to stop the server\n") + }() + + mainHandler := http.FileServer(http.Dir(*flagRootDir)) + if *flagNoCache { + mainHandler = NoCache(mainHandler) + } + log.Fatal(http.ListenAndServe(httpAddr, mainHandler)) +} + +// waitServer waits some time for the http Server to start +// serving url. The return value reports whether it starts. +func waitServer(url string) bool { + tries := 20 + for tries > 0 { + resp, err := http.Get(url) + if err == nil { + resp.Body.Close() + return true + } + time.Sleep(100 * time.Millisecond) + tries-- + } + return false +} + +func getLocalIP() string { + addrs, err := net.InterfaceAddrs() + if err != nil { + return "127.0.0.1" + } + for _, address := range addrs { + if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { + if ipnet.IP.To4() != nil { + return ipnet.IP.String() + } + } + } + return "127.0.0.1" +} + +// startBrowser tries to open the URL in a browser, and returns +// whether it succeed. +func startBrowser(url string) bool { + // try to start the browser + var args []string + switch runtime.GOOS { + case "darwin": + args = []string{"open"} + case "windows": + args = []string{"cmd", "/c", "start"} + default: + args = []string{"xdg-open"} + } + cmd := exec.Command(args[0], append(args[1:], url)...) + return cmd.Start() == nil +} + +var epoch = time.Unix(0, 0).Format(time.RFC1123) + +var noCacheHeaders = map[string]string{ + "Expires": epoch, + "Cache-Control": "no-cache, private, max-age=0", + "Pragma": "no-cache", + "X-Accel-Expires": "0", +} + +var etagHeaders = []string{ + "ETag", + "If-Modified-Since", + "If-Match", + "If-None-Match", + "If-Range", + "If-Unmodified-Since", +} + +func NoCache(h http.Handler) http.Handler { + fn := func(w http.ResponseWriter, r *http.Request) { + // Delete any ETag headers that may have been set + for _, v := range etagHeaders { + if r.Header.Get(v) != "" { + r.Header.Del(v) + } + } + + // Set our NoCache headers + for k, v := range noCacheHeaders { + w.Header().Set(k, v) + } + + h.ServeHTTP(w, r) + } + + return http.HandlerFunc(fn) +}