Example #1
0
func ExampleCreate() {
	anchorName := sanitized_anchor_name.Create("This is a header")

	fmt.Println(anchorName)

	// Output:
	// this-is-a-header
}
Example #2
0
File: block.go Project: fxnn/gone
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
}
Example #3
0
// 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
}
Example #4
0
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)
}
Example #5
0
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-世界
}
Example #6
0
// 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
}
Example #7
0
// 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")
}
Example #8
0
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()
}
Example #9
0
// 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
}
Example #10
0
File: block.go Project: fxnn/gone
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
}