class PlainSite::Data::Post

Constants

HIGHLIGHT_RE
MARKDOWN_CODE_RE

Attributes

category_path[R]
data_id[R]
filename[R]
is_index[R]
next_post[RW]
path[R]
prev_post[RW]
relpath[R]
site[R]
slug[R]

Public Class Methods

content_to_html(content,content_type) click to toggle source
# File lib/PlainSite/Data/Post.rb, line 219
def self.content_to_html(content,content_type)
  if content_type=='md'
    content=Kramdown::Document.new(content,input:'GFM').to_html
  end
  content
end
extname_ok?(f) click to toggle source
# File lib/PlainSite/Data/Post.rb, line 232
def self.extname_ok?(f)
  @@extnames.include?  File.extname(f)[1..-1]
end
extnames() click to toggle source
# File lib/PlainSite/Data/Post.rb, line 228
def self.extnames
  @@extnames
end
new(path,site) click to toggle source

Init a post path - The String file abs path,at present,only support '.html' and '.md' extname. site - The Site this post belongs to

# File lib/PlainSite/Data/Post.rb, line 37
def initialize(path,site)
  if File.directory? path # create as category index post
    path=(@@extnames.map {|x| File.join path+'/index'+x}).detect {|f| File.exists? f}
    @is_index=true
  end
  @site=site
  @path=path
  @relpath=@path[(site.data_path.length+1)..-1]

  @filename=File.basename @path
  @extname=File.extname @filename
  if DATE_NAME_RE =~ @filename
    @date=Date.new $1.to_i,$2.to_i,$3.to_i
    @slug=File.basename $4,@extname
  end
  @slug=File.basename @filename,@extname unless @slug

  @category_path=File.dirname(@relpath)

  if @category_path=='/' or @category_path=='.'
    @category_path=''
    @data_id=@slug
  else
    @data_id=File.join @category_path,@slug
  end

end

Public Instance Methods

category() click to toggle source

The Category this post belongs to

# File lib/PlainSite/Data/Post.rb, line 89
def category
  return @category if @category
  @category=Category.new File.join(@site.data_path,@category_path),@site
end
content() click to toggle source

Rendered html content It must render highlight code first. Highlight syntax:

Html tag style:
  <highlight>puts 'Hello'</highlight>
  With line numbers and language
  <highlight ruby linenos>puts 'Hello'</highlight>
  Set line number start from 10
  <highlight ruby linenos=10>puts 'Hello'</highlight>
  Highlight lines
  <highlight ruby linenos hl_lines=1>puts 'Hello'</highlight>

  Highlight html tag options:
    linenos - If provide,output will contains line number
    linenos=Int - Line number start from,default is 1
If no new line in code,the output will be inline nowrap style and no linenos.

You can also use markdown style code block,e.g. ```puts 'Code'```.
But code this style doesn't rendered by Pygments.
You need to load a browser side renderer,viz. SyntaxHighlighter.

Then render erb template,context is post itself,you can access self and self.site methods

Return the String html content

# File lib/PlainSite/Data/Post.rb, line 151
def content
  # quick fix,when build local, current path will change
  p=@path + "::"+ @site._cur_page_dir

  post_content=raw_content.dup
  # stash highlight code
  codeMap={}
  post_content.gsub! HIGHLIGHT_RE  do
    placeholder='-HIGHLIGHT '+SecureRandom.uuid+' ENDHIGHLIGHT-'
    attrs=$1
    attrs=attrs.split " "
    lexer=attrs.shift || ""
    attrs=Hash[attrs.map {|v| v.split "="}]
    attrs["hl_lines"]=(attrs["hl_lines"] || "").split ","
    code=$2
    codeMap[placeholder]={
      lexer: lexer,
      linenos: (attrs.key? "linenos") ? 'table' : false ,
      linenostart: attrs["linenos"] || 1,
      hl_lines: attrs["hl_lines"],
      code: code.strip,
      nowrap: code["\n"].nil?
    }
    placeholder
  end


  # Then render erb template if needed
  if post_content['<%'] && !post_file.headers['disable_erb']
    post_content=PlainSite::Tpl::LayErb.render_s post_content,self
  end

  post_content=self.class.content_to_html post_content,content_type

  #put back code
  codeMap.each do |k,v|
    code=Pygments.highlight v[:code],lexer: v[:lexer],formatter: 'html',options:{
        linenos: v[:linenos],
        linenostart: v[:linenostart],
        nowrap: v[:nowrap],
        hl_lines: v[:hl_lines],
        startinline: v[:lexer] == 'php'
    }
    code="<code class=\"highlight\">#{code}</code>" if v[:nowrap]
    post_content[k]=code # String#sub method has a hole of back reference
  end

  return post_content
end
content_type() click to toggle source

The String content type of post,default is it's extname without dot

# File lib/PlainSite/Data/Post.rb, line 95
def content_type
  return @content_type if @content_type
  @content_type=post_file.headers['content_type']
  @content_type=@extname[1..-1] if @content_type.nil?
  @content_type
end
date() click to toggle source

The Date of post

# File lib/PlainSite/Data/Post.rb, line 65
def date
  return @date if @date
  @date=get_date 'date'
end
get_date(k) click to toggle source
# File lib/PlainSite/Data/Post.rb, line 70
  def get_date(k)
    date=post_file.headers[k]

    date=if String===date
            begin Date.parse(date) rescue Date.today end
          elsif Date===date
            date
          else
            Date.today
          end
  end
  private :get_date

  def updated_date
    return @updated_date if @updated_date
    @updated_date=get_date 'updated_date'
  end

  # The Category this post belongs to
  def category
    return @category if @category
    @category=Category.new File.join(@site.data_path,@category_path),@site
  end

  # The String content type of post,default is it's extname without dot
  def content_type
    return @content_type if @content_type
    @content_type=post_file.headers['content_type']
    @content_type=@extname[1..-1] if @content_type.nil?
    @content_type
  end

  # The Boolean value indicates if this post is a draft,default is false,alias is `draft?`
  # def draft
  #   return @draft unless @draft.nil?
  #   @draft=!!post_file.headers['draft']
  # end
  # alias :draft? :draft

  # def deleted
  #   return @deleted unless @deleted.nil?
  #   @deleted=!!post_file.headers['deleted']
  # end
  # alias :deleted? :deleted

  # Private
  def post_file
    return @post_file if @post_file
    @post_file=FrontMatterFile.new @path
  end
  private :post_file

  # Post file raw content
  def raw_content
    post_file.content
  end

  # Rendered html content
  # It must render highlight code first.
  # Highlight syntax:
  #   Html tag style:
  #     <highlight>puts 'Hello'</highlight>
  #     With line numbers and language
  #     <highlight ruby linenos>puts 'Hello'</highlight>
  #     Set line number start from 10
  #     <highlight ruby linenos=10>puts 'Hello'</highlight>
  #     Highlight lines
  #     <highlight ruby linenos hl_lines=1>puts 'Hello'</highlight>
  #
  #     Highlight html tag options:
  #       linenos - If provide,output will contains line number
  #       linenos=Int - Line number start from,default is 1
  #   If no new line in code,the output will be inline nowrap style and no linenos.
  #
  #   You can also use markdown style code block,e.g. ```puts 'Code'```.
  #   But code this style doesn't rendered by Pygments.
  #   You need to load a browser side renderer,viz. SyntaxHighlighter.
  #
  # Then render erb template,context is post itself,you can access self and self.site methods
  #
  # Return the String html content
  def content
    # quick fix,when build local, current path will change
    p=@path + "::"+ @site._cur_page_dir

    post_content=raw_content.dup
    # stash highlight code
    codeMap={}
    post_content.gsub! HIGHLIGHT_RE  do
      placeholder='-HIGHLIGHT '+SecureRandom.uuid+' ENDHIGHLIGHT-'
      attrs=$1
      attrs=attrs.split " "
      lexer=attrs.shift || ""
      attrs=Hash[attrs.map {|v| v.split "="}]
      attrs["hl_lines"]=(attrs["hl_lines"] || "").split ","
      code=$2
      codeMap[placeholder]={
        lexer: lexer,
        linenos: (attrs.key? "linenos") ? 'table' : false ,
        linenostart: attrs["linenos"] || 1,
        hl_lines: attrs["hl_lines"],
        code: code.strip,
        nowrap: code["\n"].nil?
      }
      placeholder
    end


    # Then render erb template if needed
    if post_content['<%'] && !post_file.headers['disable_erb']
      post_content=PlainSite::Tpl::LayErb.render_s post_content,self
    end

    post_content=self.class.content_to_html post_content,content_type

    #put back code
    codeMap.each do |k,v|
      code=Pygments.highlight v[:code],lexer: v[:lexer],formatter: 'html',options:{
          linenos: v[:linenos],
          linenostart: v[:linenostart],
          nowrap: v[:nowrap],
          hl_lines: v[:hl_lines],
          startinline: v[:lexer] == 'php'
      }
      code="<code class=\"highlight\">#{code}</code>" if v[:nowrap]
      post_content[k]=code # String#sub method has a hole of back reference
    end

    return post_content
  end

  # The String url of this post in site
  def url
    @site.url_for @data_id
  end

  # You can use method call to access post file front-matter data
  def respond_to?(name)
    return true if post_file.headers.key? name.to_s
    super
  end

  def method_missing(name,*args,&block)
    if args.length==0 && block.nil? &&  post_file.headers.key?(name.to_s)
      return post_file.headers[name.to_s]
    end
    super
  end

  def self.content_to_html(content,content_type)
    if content_type=='md'
      content=Kramdown::Document.new(content,input:'GFM').to_html
    end
    content
  end

  @@extnames=['md','html']

  def self.extnames
    @@extnames
  end

  def self.extname_ok?(f)
    @@extnames.include?  File.extname(f)[1..-1]
  end

end
method_missing(name,*args,&block) click to toggle source
Calls superclass method
# File lib/PlainSite/Data/Post.rb, line 212
def method_missing(name,*args,&block)
  if args.length==0 && block.nil? &&  post_file.headers.key?(name.to_s)
    return post_file.headers[name.to_s]
  end
  super
end
post_file() click to toggle source

Private

# File lib/PlainSite/Data/Post.rb, line 116
def post_file
  return @post_file if @post_file
  @post_file=FrontMatterFile.new @path
end
raw_content() click to toggle source

Post file raw content

# File lib/PlainSite/Data/Post.rb, line 123
def raw_content
  post_file.content
end
respond_to?(name) click to toggle source

You can use method call to access post file front-matter data

Calls superclass method
# File lib/PlainSite/Data/Post.rb, line 207
def respond_to?(name)
  return true if post_file.headers.key? name.to_s
  super
end
updated_date() click to toggle source
# File lib/PlainSite/Data/Post.rb, line 83
def updated_date
  return @updated_date if @updated_date
  @updated_date=get_date 'updated_date'
end
url() click to toggle source

The String url of this post in site

# File lib/PlainSite/Data/Post.rb, line 202
def url
  @site.url_for @data_id
end