初始化项目
This commit is contained in:
parent
c0eba18e88
commit
b8489d4629
|
@ -1,3 +1,7 @@
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
go.sum
|
||||||
|
|
||||||
# If you prefer the allow list template instead of the deny list, see community template:
|
# If you prefer the allow list template instead of the deny list, see community template:
|
||||||
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
||||||
#
|
#
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
# 项目介绍
|
||||||
|
本项目初衷是为了实现markdown的文档的展示
|
||||||
|
|
||||||
|
# 实现方式
|
||||||
|
|
||||||
|
该项目使用gin实现,markdown使用`gomarkdown/markdown`渲染成html代码块。由templates渲染到页面中
|
||||||
|
|
||||||
|
# 配置
|
||||||
|
```yaml
|
||||||
|
server:
|
||||||
|
port: 8081
|
||||||
|
dir:
|
||||||
|
root: \Gitlab\note
|
||||||
|
main: 专栏
|
||||||
|
|
||||||
|
```
|
|
@ -0,0 +1,5 @@
|
||||||
|
server:
|
||||||
|
port: 8081
|
||||||
|
dir:
|
||||||
|
root: \Gitlab\note
|
||||||
|
main: PDF
|
|
@ -0,0 +1,60 @@
|
||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gin-demo/response"
|
||||||
|
"gin-demo/util"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CategoryController struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func MarkdownLoad() CategoryController {
|
||||||
|
return CategoryController{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CategoryController) Show(ctx *gin.Context) {
|
||||||
|
urlPath := ""
|
||||||
|
urlPath = ctx.Request.URL.Path
|
||||||
|
//fmt.Println(urlPath)
|
||||||
|
|
||||||
|
if strings.HasPrefix(urlPath, "/static") {
|
||||||
|
if _, err := os.Stat("." + urlPath); err == nil {
|
||||||
|
ctx.File("." + urlPath)
|
||||||
|
ctx.Header("Cache-Control", "public,s-maxage=300,max-age=31536000")
|
||||||
|
ctx.Abort() // file found, stop the handler chain
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rootDir := viper.GetString("dir.root")
|
||||||
|
path := rootDir + urlPath
|
||||||
|
pathInfo, err := os.Stat(path)
|
||||||
|
listResult := util.GetFileList(path)
|
||||||
|
if err != nil {
|
||||||
|
response.Fail(ctx, gin.H{})
|
||||||
|
|
||||||
|
}
|
||||||
|
if pathInfo.IsDir() {
|
||||||
|
if urlPath == "/" {
|
||||||
|
path = path + viper.GetString("dir.main")
|
||||||
|
}
|
||||||
|
htmlContext := util.GetDirStr(path)
|
||||||
|
//fmt.Println(htmlContext)
|
||||||
|
response.Success(ctx, gin.H{"title": pathInfo.Name(), "htmlContext": htmlContext, "list": listResult})
|
||||||
|
} else if strings.HasSuffix(pathInfo.Name(), ".md") {
|
||||||
|
// 后缀判断
|
||||||
|
htmlContext := util.GetMdStr(path)
|
||||||
|
//fmt.Println(htmlContext)
|
||||||
|
title := pathInfo.Name()
|
||||||
|
title = strings.ReplaceAll(title, ".md", "")
|
||||||
|
response.Success(ctx, gin.H{"title": title, "htmlContext": htmlContext, "list": listResult})
|
||||||
|
} else {
|
||||||
|
ctx.Header("Cache-Control", "public,s-maxage=300,max-age=31536000")
|
||||||
|
ctx.File(path)
|
||||||
|
ctx.Abort()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
module gin-demo
|
||||||
|
|
||||||
|
go 1.16
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/gin-gonic/gin v1.8.1
|
||||||
|
github.com/gomarkdown/markdown v0.0.0-20230716120725-531d2d74bc12
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
|
github.com/spf13/viper v1.6.3
|
||||||
|
golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2 // indirect
|
||||||
|
)
|
|
@ -0,0 +1,34 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gin-demo/route"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
InitConfig()
|
||||||
|
|
||||||
|
r := gin.Default()
|
||||||
|
r.LoadHTMLGlob("templates/*.html")
|
||||||
|
// r.StaticFS("/static", http.Dir("./static"))
|
||||||
|
r = route.CollectRoute(r)
|
||||||
|
port := viper.GetString("server.port")
|
||||||
|
if port != "" {
|
||||||
|
panic(r.Run(":" + port))
|
||||||
|
}
|
||||||
|
panic(r.Run()) // listen and serve on 0.0.0.0:8080
|
||||||
|
}
|
||||||
|
|
||||||
|
func InitConfig() {
|
||||||
|
workDir, _ := os.Getwd()
|
||||||
|
viper.SetConfigName("application")
|
||||||
|
viper.SetConfigType("yml")
|
||||||
|
viper.AddConfigPath(workDir + "/config")
|
||||||
|
err := viper.ReadInConfig()
|
||||||
|
if err != nil {
|
||||||
|
panic("")
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package response
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Response(ctx *gin.Context, httpStatus int, data gin.H) {
|
||||||
|
ctx.HTML(httpStatus, "index.html", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Success(ctx *gin.Context, data gin.H) {
|
||||||
|
Response(ctx, http.StatusOK, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Fail(ctx *gin.Context, data gin.H) {
|
||||||
|
ctx.HTML(http.StatusNotFound, "404.html", data)
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package route
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gin-demo/controller"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CollectRoute(r *gin.Engine) *gin.Engine {
|
||||||
|
categoryController := controller.MarkdownLoad()
|
||||||
|
r.GET("/*path", categoryController.Show)
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 6.2 KiB |
|
@ -0,0 +1,9 @@
|
||||||
|
/*!
|
||||||
|
Theme: Default
|
||||||
|
Description: Original highlight.js style
|
||||||
|
Author: (c) Ivan Sagalaev <maniac@softwaremaniacs.org>
|
||||||
|
Maintainer: @highlightjs/core-team
|
||||||
|
Website: https://highlightjs.org/
|
||||||
|
License: see project LICENSE
|
||||||
|
Touched: 2021
|
||||||
|
*/pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#f3f3f3;color:#444}.hljs-comment{color:#697070}.hljs-punctuation,.hljs-tag{color:#444a}.hljs-tag .hljs-attr,.hljs-tag .hljs-name{color:#444}.hljs-attribute,.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-name,.hljs-selector-tag{font-weight:700}.hljs-deletion,.hljs-number,.hljs-quote,.hljs-selector-class,.hljs-selector-id,.hljs-string,.hljs-template-tag,.hljs-type{color:#800}.hljs-section,.hljs-title{color:#800;font-weight:700}.hljs-link,.hljs-operator,.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#ab5656}.hljs-literal{color:#695}.hljs-addition,.hljs-built_in,.hljs-bullet,.hljs-code{color:#397300}.hljs-meta{color:#1f7199}.hljs-meta .hljs-string{color:#38a}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,97 @@
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
|
||||||
|
function gtag() {
|
||||||
|
dataLayer.push(arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtag('js', new Date());
|
||||||
|
gtag('config', 'G-NPSEEVD756');
|
||||||
|
var path = window.location.pathname
|
||||||
|
var cookie = getCookie("lastPath");
|
||||||
|
console.log(path)
|
||||||
|
if (path.replace("/", "") === "") {
|
||||||
|
if (cookie.replace("/", "") !== "") {
|
||||||
|
console.log(cookie)
|
||||||
|
document.getElementById("tip").innerHTML = "<a href='" + cookie + "'>跳转到上次进度</a>"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setCookie("lastPath", path)
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onload = function () {
|
||||||
|
var title = document.title
|
||||||
|
var ele = document.getElementById(title + ".md");
|
||||||
|
if (ele) {
|
||||||
|
ele.classList.add("current-tab")
|
||||||
|
}
|
||||||
|
var eleList = document.getElementsByClassName("menu-item")
|
||||||
|
for (var i = 0; i < eleList.length; i++) { //遍历数组
|
||||||
|
if (eleList[i].id.startsWith(title) && i > 0) {
|
||||||
|
document.getElementById("prePage").innerHTML = "<a href='" + eleList[i - 1].getAttribute("href") + "'>上一页</a>"
|
||||||
|
}
|
||||||
|
if (eleList[i].id.startsWith(title) && i < eleList.length) {
|
||||||
|
document.getElementById("nextPage").innerHTML = "<a href='" + eleList[i + 1].getAttribute("href") + "'>下一页</a>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setCookie(cname, cvalue) {
|
||||||
|
var d = new Date();
|
||||||
|
d.setTime(d.getTime() + (180 * 24 * 60 * 60 * 1000));
|
||||||
|
var expires = "expires=" + d.toGMTString();
|
||||||
|
document.cookie = cname + "=" + cvalue + "; " + expires + ";path = /";
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCookie(cname) {
|
||||||
|
var name = cname + "=";
|
||||||
|
var ca = document.cookie.split(';');
|
||||||
|
for (var i = 0; i < ca.length; i++) {
|
||||||
|
var c = ca[i].trim();
|
||||||
|
if (c.indexOf(name) === 0) return c.substring(name.length, c.length);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
hljs.initHighlightingOnLoad()
|
||||||
|
|
||||||
|
function add_inner() {
|
||||||
|
let inner = document.querySelector('.sidebar-toggle-inner')
|
||||||
|
inner.classList.add('show')
|
||||||
|
}
|
||||||
|
|
||||||
|
function remove_inner() {
|
||||||
|
let inner = document.querySelector('.sidebar-toggle-inner')
|
||||||
|
inner.classList.remove('show')
|
||||||
|
}
|
||||||
|
|
||||||
|
function sidebar_toggle() {
|
||||||
|
let sidebar_toggle = document.querySelector('.sidebar-toggle')
|
||||||
|
let sidebar = document.querySelector('.book-sidebar')
|
||||||
|
let content = document.querySelector('.off-canvas-content')
|
||||||
|
if (sidebar_toggle.classList.contains('extend')) { // show
|
||||||
|
sidebar_toggle.classList.remove('extend')
|
||||||
|
sidebar.classList.remove('hide')
|
||||||
|
content.classList.remove('extend')
|
||||||
|
} else { // hide
|
||||||
|
sidebar_toggle.classList.add('extend')
|
||||||
|
sidebar.classList.add('hide')
|
||||||
|
content.classList.add('extend')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function open_sidebar() {
|
||||||
|
let sidebar = document.querySelector('.book-sidebar')
|
||||||
|
let overlay = document.querySelector('.off-canvas-overlay')
|
||||||
|
sidebar.classList.add('show')
|
||||||
|
overlay.classList.add('show')
|
||||||
|
}
|
||||||
|
function hide_canvas() {
|
||||||
|
let sidebar = document.querySelector('.book-sidebar')
|
||||||
|
let overlay = document.querySelector('.off-canvas-overlay')
|
||||||
|
sidebar.classList.remove('show')
|
||||||
|
overlay.classList.remove('show')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<!-- saved from url=(0027)https://www.dropbox.com/404 -->
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<title>404</title>
|
||||||
|
</head>
|
||||||
|
<style>
|
||||||
|
body,input,textarea,select,button,.normal {
|
||||||
|
font-family: "Open Sans","lucida grande","Segoe UI",arial,verdana,"lucida sans unicode",tahoma,sans-serif;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #000;
|
||||||
|
font-weight: normal
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
color: #444;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: normal;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#errorbox {
|
||||||
|
line-height: 1.6em;
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: 600px;
|
||||||
|
padding: 0 20px;
|
||||||
|
text-align: left;
|
||||||
|
word-wrap: break-word
|
||||||
|
}
|
||||||
|
|
||||||
|
#errorbox a {
|
||||||
|
color: #005ff8;
|
||||||
|
text-decoration: none
|
||||||
|
}
|
||||||
|
|
||||||
|
#errorbox h1 {
|
||||||
|
color: #222;
|
||||||
|
font-size: 1.5em;
|
||||||
|
font-weight: normal;
|
||||||
|
margin: 10px 0
|
||||||
|
}
|
||||||
|
|
||||||
|
#errorbox .not-found {
|
||||||
|
color: rgba(0,0,0,0.75);
|
||||||
|
font-size: 21px;
|
||||||
|
font-weight: lighter;
|
||||||
|
line-height: 36px;
|
||||||
|
text-align: center
|
||||||
|
}
|
||||||
|
|
||||||
|
#errorbox .not-found h1 {
|
||||||
|
color: rgba(0,0,0,0.75);
|
||||||
|
font-size: 38px;
|
||||||
|
font-weight: lighter;
|
||||||
|
line-height: 47px
|
||||||
|
}
|
||||||
|
|
||||||
|
#errorbox .not-found--links {
|
||||||
|
margin: 48px 0;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 20px
|
||||||
|
}
|
||||||
|
|
||||||
|
#errorbox .not-found--links ul {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
list-style-type: none
|
||||||
|
}
|
||||||
|
|
||||||
|
#errorbox .not-found--links ul li {
|
||||||
|
margin-top: 10px
|
||||||
|
}
|
||||||
|
|
||||||
|
#errorbox .not-found--links ul li a:hover {
|
||||||
|
text-decoration: underline
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<body>
|
||||||
|
<div id="errorbox">
|
||||||
|
<div class="not-found"><h1>Error (404)</h1>
|
||||||
|
<div class="not-found--links">
|
||||||
|
<ul>
|
||||||
|
<li><a href="/">Home</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,100 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
|
||||||
|
<meta http-equiv='content-language' content='zh-cn'>
|
||||||
|
<meta name='description' content={{.title}}>
|
||||||
|
<link rel="icon" href="/static/favicon.png">
|
||||||
|
<title >{{.title}} </title>
|
||||||
|
<!-- Spectre.css framework -->
|
||||||
|
<link rel="stylesheet" href="/static/index.css">
|
||||||
|
<link rel="stylesheet" href="/static/highlight.min.css">
|
||||||
|
<script src="/static/highlight.min.js"></script>
|
||||||
|
<!-- theme css & js -->
|
||||||
|
<meta name="generator" content="Hexo 4.2.0">
|
||||||
|
<script async defer data-website-id="83e5d5db-9d06-40e3-b780-cbae722fdf8c"
|
||||||
|
src="http://analyze.lianglianglee.com/umami.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="book-container">
|
||||||
|
<div class="book-sidebar">
|
||||||
|
<div class="book-brand">
|
||||||
|
<a href="/">
|
||||||
|
<img src="/static/favicon.png">
|
||||||
|
<span>技术文章摘抄</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="book-menu uncollapsible">
|
||||||
|
<ul class="uncollapsible">
|
||||||
|
<li><a href="/" class="current-tab">首页</a></li>
|
||||||
|
<li><a href="../">上一级</a></li>
|
||||||
|
</ul>
|
||||||
|
<ul class="uncollapsible">
|
||||||
|
{{range $i, $v := .list}}
|
||||||
|
<li>
|
||||||
|
<a class ="menu-item" id="{{$v.FileName}}" href="{{$v.FilePath}}">{{$v.FileName}}</a>
|
||||||
|
</li>
|
||||||
|
{{end}}
|
||||||
|
<li><a href="/assets/捐赠.md">捐赠</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sidebar-toggle" onclick="sidebar_toggle()" onmouseover="add_inner()" onmouseleave="remove_inner()">
|
||||||
|
<div class="sidebar-toggle-inner"></div>
|
||||||
|
</div>
|
||||||
|
<div class="off-canvas-content">
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column col-12 col-lg-12">
|
||||||
|
<div class="book-navbar">
|
||||||
|
<!-- For Responsive Layout -->
|
||||||
|
<header class="navbar">
|
||||||
|
<section class="navbar-section">
|
||||||
|
<a onclick="open_sidebar()">
|
||||||
|
<i class="icon icon-menu"></i>
|
||||||
|
</a>
|
||||||
|
</section>
|
||||||
|
</header>
|
||||||
|
</div>
|
||||||
|
<div class="book-content" style="max-width: 960px; margin: 0 auto;
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: hidden;">
|
||||||
|
<div class="book-post">
|
||||||
|
<p id="tip" align="center"></p>
|
||||||
|
<p class="title">{{.title}}</p>
|
||||||
|
<div>{{ .htmlContext }}</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div id="prePage" style="float: left">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div id="nextPage" style="float: right">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="copyright">
|
||||||
|
<hr />
|
||||||
|
<p>© 2019 - 2023 <a href="mailto:lll941107@gmail.com" target="_blank">Liangliang Lee</a>.
|
||||||
|
Powered by <a href="https://github.com/gin-gonic/gin" target="_blank">gin</a> and <a
|
||||||
|
href="https://github.com/kaiiiz/hexo-theme-book" target="_blank">hexo-theme-book</a>.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a class="off-canvas-overlay" onclick="hide_canvas()"></a>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||||
|
<script async src="https://www.googletagmanager.com/gtag/js?id=G-NPSEEVD756"></script>
|
||||||
|
|
||||||
|
<script src="/static/index.js"></script>
|
||||||
|
|
||||||
|
</html>
|
|
@ -0,0 +1,6 @@
|
||||||
|
package util
|
||||||
|
|
||||||
|
type FileModel struct {
|
||||||
|
FileName string
|
||||||
|
FilePath string
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"html/template"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gomarkdown/markdown"
|
||||||
|
"github.com/gomarkdown/markdown/html"
|
||||||
|
"github.com/gomarkdown/markdown/parser"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetMdStr(path string) template.HTML {
|
||||||
|
fileMeta, err := os.Stat(path)
|
||||||
|
if err != nil {
|
||||||
|
return "读取错误"
|
||||||
|
}
|
||||||
|
if fileMeta.IsDir() {
|
||||||
|
return GetDirStr(path)
|
||||||
|
} else {
|
||||||
|
context, err := os.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return "error"
|
||||||
|
}
|
||||||
|
htmlContext := MdToHtml(context)
|
||||||
|
html := template.HTML(htmlContext)
|
||||||
|
return html
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDirStr(path string) template.HTML {
|
||||||
|
listResult := GetFileList(path)
|
||||||
|
context := ""
|
||||||
|
for i := 0; i < len(listResult); i++ {
|
||||||
|
item := listResult[i]
|
||||||
|
if !strings.HasPrefix(item.FileName, ".") && item.FileName != "assets" {
|
||||||
|
context += "- [" + item.FileName + "](" + item.FilePath + ") \n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
htmlContext := MdToHtml([]byte(context))
|
||||||
|
html := template.HTML(htmlContext)
|
||||||
|
return html
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFileList(path string) []FileModel {
|
||||||
|
var result []FileModel
|
||||||
|
fileMeta, err := os.Stat(path)
|
||||||
|
if err != nil {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
rootDir := viper.GetString("dir.root")
|
||||||
|
if !fileMeta.IsDir() {
|
||||||
|
path = filepath.Dir(path)
|
||||||
|
}
|
||||||
|
list, err := os.ReadDir(path)
|
||||||
|
if err != nil {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
for i := 0; i < len(list); i++ {
|
||||||
|
item := list[i]
|
||||||
|
fileInfo, err := item.Info()
|
||||||
|
//fmt.Println(fileInfo.Name())
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(fileInfo.Name(), ".") || fileInfo.Name() == "assets" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !strings.HasSuffix(path, "/") {
|
||||||
|
path = path + "/"
|
||||||
|
}
|
||||||
|
filePath := strings.Replace(path+fileInfo.Name(), rootDir, "", -1)
|
||||||
|
if !strings.HasPrefix(filePath, "/") {
|
||||||
|
filePath = "/" + filePath
|
||||||
|
}
|
||||||
|
result = append(result, FileModel{FileName: fileInfo.Name(), FilePath: filePath})
|
||||||
|
}
|
||||||
|
// 用 age 排序,年龄相等的元素保持原始顺序
|
||||||
|
sort.SliceStable(result, func(i, j int) bool {
|
||||||
|
return result[i].FileName < result[j].FileName
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func MdToHtml(context []byte) []byte {
|
||||||
|
// create markdown parser with extensions
|
||||||
|
extensions := parser.CommonExtensions | parser.AutoHeadingIDs | parser.NoEmptyLineBeforeBlock
|
||||||
|
p := parser.NewWithExtensions(extensions)
|
||||||
|
doc := p.Parse(context)
|
||||||
|
|
||||||
|
// create HTML renderer with extensions
|
||||||
|
htmlFlags := html.CommonFlags | html.HrefTargetBlank
|
||||||
|
opts := html.RendererOptions{Flags: htmlFlags}
|
||||||
|
renderer := html.NewRenderer(opts)
|
||||||
|
|
||||||
|
return markdown.Render(doc, renderer)
|
||||||
|
}
|
Loading…
Reference in New Issue