func ExampleCreate() { anchorName := sanitized_anchor_name.Create("This is a header") fmt.Println(anchorName) // Output: // this-is-a-header }
func (p *parser) prefixHeader(out *bytes.Buffer, data []byte) int { level := 0 for level < 6 && data[level] == '#' { level++ } i := skipChar(data, level, ' ') end := skipUntilChar(data, i, '\n') skip := end id := "" if p.flags&EXTENSION_HEADER_IDS != 0 { j, k := 0, 0 // find start/end of header id for j = i; j < end-1 && (data[j] != '{' || data[j+1] != '#'); j++ { } for k = j + 1; k < end && data[k] != '}'; k++ { } // extract header id iff found if j < end && k < end { id = string(data[j+2 : k]) end = j skip = k + 1 for end > 0 && data[end-1] == ' ' { end-- } } } for end > 0 && data[end-1] == '#' { if isBackslashEscaped(data, end-1) { break } end-- } for end > 0 && data[end-1] == ' ' { end-- } if end > i { if id == "" && p.flags&EXTENSION_AUTO_HEADER_IDS != 0 { id = sanitized_anchor_name.Create(string(data[i:end])) } work := func() bool { p.inline(out, data[i:end]) return true } p.r.Header(out, work, level, id) } return skip }
// Update or post.Update updates parameter "entry" with data given in parameter "post". // Requires active session cookie. // Returns updated Post object and an error object. func (post Post) Update(entry Post) (Post, error) { entry.ID = post.ID entry.Content = string(blackfriday.MarkdownCommon([]byte(entry.Markdown))) entry.Excerpt = excerpt.Make(entry.Content, 15) entry.Slug = slug.Create(entry.Title) entry.Updated = time.Now().UTC().Round(time.Second).Unix() _, err := db.NamedExec( "UPDATE posts SET title = :title, content = :content, markdown = :markdown, slug = :slug, excerpt = :excerpt, published = :published, updated = :updated WHERE id = :id", entry) if err != nil { return post, err } entry.Viewcount = post.Viewcount entry.Created = post.Created entry.TimeOffset = post.TimeOffset entry.Author = post.Author return entry, nil }
func testCreatePost(t *testing.T, owner int64, title string, markdown string) { var u User u.ID = owner var p Post p.ID = post.ID + 1 p.Title = title p.Markdown = markdown p.Content = string(blackfriday.MarkdownCommon([]byte(markdown))) p.Slug = slug.Create(p.Title) p.Author = u.ID p.Excerpt = excerpt.Make(p.Content, 15) p.Viewcount = 0 payload, err := json.Marshal(p) if err != nil { panic(err) } testCreatePostRequest(t, payload, p) }
func ExampleCreate_two() { fmt.Println(sanitized_anchor_name.Create("This is a header")) fmt.Println(sanitized_anchor_name.Create("This is also a header")) fmt.Println(sanitized_anchor_name.Create("main.go")) fmt.Println(sanitized_anchor_name.Create("Article 123")) fmt.Println(sanitized_anchor_name.Create("<- Let's try this, shall we?")) fmt.Printf("%q\n", sanitized_anchor_name.Create(" ")) fmt.Println(sanitized_anchor_name.Create("Hello, 世界")) // Output: // this-is-a-header // this-is-also-a-header // main-go // article-123 // let-s-try-this-shall-we // "" // hello-世界 }
// Insert or post.Insert inserts Post object into database. // Requires active session cookie // Fills post.Author, post.Created, post.Edited, post.Excerpt, post.Slug and post.Published automatically. // Returns Post and error object. func (post Post) Insert(user User) (Post, error) { _, offset, err := timezone.Offset(user.Location) if err != nil { return post, err } post.TimeOffset = offset post.Content = string(blackfriday.MarkdownCommon([]byte(post.Markdown))) post.Author = user.ID post.Created = time.Now().UTC().Round(time.Second).Unix() post.Updated = post.Created post.Excerpt = excerpt.Make(post.Content, 15) post.Slug = slug.Create(post.Title) post.Published = false post.Viewcount = 0 _, err = db.NamedExec(`INSERT INTO posts (title, content, markdown, slug, author, excerpt, viewcount, published, created, updated, timeoffset) VALUES (:title, :content, :markdown, :slug, :author, :excerpt, :viewcount, :published, :created, :updated, :timeoffset)`, post) if err != nil { return post, err } return post, nil }
// Update or post.Update updates parameter "entry" with data given in parameter "post". // Requires active session cookie. // Returns updated Post object and an error object. func (post Post) Update(s sessions.Session, entry Post) (Post, error) { var user User user, err := user.Session(s) if err != nil { return post, err } if post.Author == user.ID { entry.Content = string(blackfriday.MarkdownCommon([]byte(entry.Markdown))) entry.Excerpt = Excerpt(entry.Content) entry.Slug = slug.Create(entry.Title) entry.Updated = time.Now().UTC().Unix() query := connection.Gorm.Where(&Post{Slug: post.Slug, Author: user.ID}).First(&post).Updates(entry) if query.Error != nil { if query.Error == gorm.RecordNotFound { return post, errors.New("not found") } return post, query.Error } return post, nil } return post, errors.New("unauthorized") }
func setup() { headers = document.Body().GetElementsByTagName("h2") if len(headers) == 0 { return } overlay := document.CreateElement("div") overlay.SetID("toc-overlay") results = document.CreateElement("div").(*dom.HTMLDivElement) results.SetID("toc-results") for _, header := range headers { element := document.CreateElement("div").(*dom.HTMLDivElement) element.Class().Add("toc-entry") element.SetTextContent(header.TextContent()) href := "#" + sanitized_anchor_name.Create(header.TextContent()) target := header.(dom.HTMLElement) element.AddEventListener("click", false, func(event dom.Event) { //dom.GetWindow().History().ReplaceState(nil, nil, href) js.Global.Get("window").Get("history").Call("replaceState", nil, nil, href) windowHalfHeight := dom.GetWindow().InnerHeight() * 2 / 5 dom.GetWindow().ScrollTo(dom.GetWindow().ScrollX(), int(target.OffsetTop()+target.OffsetHeight())-windowHalfHeight) }) results.AppendChild(element) } overlay.AppendChild(results) document.Body().AppendChild(overlay) dom.GetWindow().AddEventListener("scroll", false, func(event dom.Event) { updateToc() }) updateToc() }
// Insert or post.Insert inserts Post object into database. // Requires active session cookie // Fills post.Author, post.Created, post.Edited, post.Excerpt, post.Slug and post.Published automatically. // Returns Post and error object. func (post Post) Insert(s sessions.Session) (Post, error) { var user User user, err := user.Session(s) if err != nil { return post, err } timeOffset, err := TimeOffset(user.Location) if err != nil { return post, err } post.TimeOffset = timeOffset post.Content = string(blackfriday.MarkdownCommon([]byte(post.Markdown))) post.Author = user.ID post.Created = time.Now().UTC().Unix() post.Updated = post.Created post.Excerpt = Excerpt(post.Content) post.Slug = slug.Create(post.Title) post.Published = false query := connection.Gorm.Create(&post) if query.Error != nil { return post, query.Error } return post, nil }
func (p *parser) paragraph(out *bytes.Buffer, data []byte) int { // prev: index of 1st char of previous line // line: index of 1st char of current line // i: index of cursor/end of current line var prev, line, i int // keep going until we find something to mark the end of the paragraph for i < len(data) { // mark the beginning of the current line prev = line current := data[i:] line = i // did we find a blank line marking the end of the paragraph? if n := p.isEmpty(current); n > 0 { p.renderParagraph(out, data[:i]) return i + n } // an underline under some text marks a header, so our paragraph ended on prev line if i > 0 { if level := p.isUnderlinedHeader(current); level > 0 { // render the paragraph p.renderParagraph(out, data[:prev]) // ignore leading and trailing whitespace eol := i - 1 for prev < eol && data[prev] == ' ' { prev++ } for eol > prev && data[eol-1] == ' ' { eol-- } // render the header // this ugly double closure avoids forcing variables onto the heap work := func(o *bytes.Buffer, pp *parser, d []byte) func() bool { return func() bool { pp.inline(o, d) return true } }(out, p, data[prev:eol]) id := "" if p.flags&EXTENSION_AUTO_HEADER_IDS != 0 { id = sanitized_anchor_name.Create(string(data[prev:eol])) } p.r.Header(out, work, level, id) // find the end of the underline for data[i] != '\n' { i++ } return i } } // if the next line starts a block of HTML, then the paragraph ends here if p.flags&EXTENSION_LAX_HTML_BLOCKS != 0 { if data[i] == '<' && p.html(out, current, false) > 0 { // rewind to before the HTML block p.renderParagraph(out, data[:i]) return i } } // if there's a prefixed header or a horizontal rule after this, paragraph is over if p.isPrefixHeader(current) || p.isHRule(current) { p.renderParagraph(out, data[:i]) return i } // if there's a list after this, paragraph is over if p.flags&EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK != 0 { if p.uliPrefix(current) != 0 || p.oliPrefix(current) != 0 || p.quotePrefix(current) != 0 || p.codePrefix(current) != 0 { p.renderParagraph(out, data[:i]) return i } } // otherwise, scan to the beginning of the next line for data[i] != '\n' { i++ } i++ } p.renderParagraph(out, data[:i]) return i }