Get the full filename of the post in convecter of Jekyll - ruby

I am using markdown extension in jekyll using convecter. For example:
module Jekyll
class MyConverter < Converter
safe false
priority :high
def matches(ext)
ext =~ /^.(md|markdown)$/i
end
def output_ext(ext)
".html"
end
def my_process (content)
# something
end
def convert(content)
# Here my markdown processing
# content = my_process(content)
# Here I want to use the path to the markdown file
# puts (filename)
site = Jekyll::Site.new(#config)
converter = site.find_converter_instance(Jekyll::Converters::Markdown)
converter.convert(content)
end
end
end
Is it possible to get the full name of the file or its location for which markdown text is converted to html?
For example, I have a markdown file:
Bla bla bla.
[Text of the link](gallery)
Bla bla bla
And I want a list of the files in directory gallery. How to get a list of files from a specific directory I know, but in the convecter I need to know the full path to this markdown file. Is there any way to do that?

Use Jekyll::Hook:
module Jekyll
class MyHookProcess
class << self
def my_process(content)
# something
content
end
end
end
end
Jekyll::Hooks.register([:posts], :pre_render) do |post|
#puts ("post.date = " + post.date)
#puts ("post.path = " + post.path)
#puts ("post.url = " + post.url)
post.content = Jekyll::MyHookProcess.my_process(post.content)
end

Related

Using Liquid custom tags to output multiple `span` elements`

I'm playing with Jekyll plugins and their ability to create custom tags and I've run into an issue extending my tag to accept a comma separated list.
I started with the following:
{% symbol R %}
And the matching plugin code:
module Jekyll
class Symbol < Liquid::Tag
def initialize(tag_name, text, tokens)
super
#text = text
end
def render(context)
"<span class='symbol-#{#text}'>#{#text}</span>"
end
end
end
Liquid::Template.register_tag('symbol', Jekyll::Symbol)
And the output on my page, as expected, is:
<span class="symbol-R">R</span>
What I'm trying to do now is amend this plugin so I can pass in a comma separated list, for example:
{% symbol R,G %}
I updated my plugin code to this:
module Jekyll
class Symbol < Liquid::Tag
def initialize(tag_name, text, tokens)
super
#text = text
end
def render(context)
symbol = #text.split(',').map(&:strip)
symbol.each do |item|
puts item # to test in terminal
"<span class='symbol-#{#text}'>#{#text}</span>"
end
end
end
end
Liquid::Template.register_tag('symbol', Jekyll::Symbol)
Terminal outputs correctly:
R
G
And my expectation was that I'd get the following on my page:
<span class="symbol-R">R</span><span class="symbol-G">G</span>
But all that shows up on the page is:
RG
Could I get some help in figuring this out? I feel like I'm super close... it's just the actual page rendering I'm clearly messing up on.
In Ruby your function will return the last expression that it executed. For you, this is the symbol.each do … end.
each returns various things, but what it does not do by itself is return the contents of its block. For that, you want map:
symbol.map do |item|
puts item # to test in terminal
"<span class='symbol-#{#text}'>#{#text}</span>"
end
Replace
symbol.each do |item|
puts item # to test in terminal
"<span class='symbol-#{#text}'>#{#text}</span>"
end
by
output = ""
symbol.each do |item|
output =+ "<span class='symbol-#{item}'>#{item}</span>"
end
output

Create a plugin that puts text in a .txt file

I am working on creating a plugin in Ruby.
On this moment I am unable to insert the coordinates, that are added to a Sketchup model, in a .txt file.
This is my code:
require 'sketchup.rb'
SKETCHUP_CONSOLE.show rescue Sketchup.send_action("showRubyPanel:")
$stdout = File.new('file.txt', 'w')
module HWmakemyownplug
def self.fileplug
model = Sketchup.active_model
#Make some coordinates.
coordinates = [[2,0,39],[0,0,1],[1,1,0]]
#Add the points in Sketchup. This works!
coordinates.each { |point| model.active_entities.add_cpoint(point) }
#Puts the coordinates to the textfile 'file.txt'. This doesn't work!
$stdout.puts(coordinates)
end #def self.fileplug
end #module makemyownplug
if (!file_loaded?(__FILE__))
#Add to the SketchUp tools menu
extensions_menu = UI.menu("Plugins")
extensions_menu.add_item("testtesttest") { HWmakemyownplug::fileplug }
# Let Ruby know we have loaded this file
file_loaded(__FILE__)
end
The coordinates have to be printed when I click on menu > plugins > testtesttest.
You forgot to close file after $stdout.puts(coordinates)
$stdout.close
Here is an example code for writing data to a JSON file instead of a simple text document.
The code can run outside of SketchUp for testing in the terminal. Just make sure to follow these steps...
Copy the code below and paste it on a ruby file (example: file.rb)
Run the script in terminal ruby file.rb or run with SketchUp.
The script will write data to JSON file and also read the content of JSON file.
The path to the JSON file is relative to the ruby file created in step one. If the script can't find the path it will create the JSON file for you.
module DeveloperName
module PluginName
require 'json'
require 'fileutils'
class Main
def initialize
path = File.dirname(__FILE__)
#json = File.join(path, 'file.json')
#content = { 'hello' => 'hello world' }.to_json
json_create(#content)
json_read(#json)
end
def json_create(content)
File.open(#json, 'w') { |f| f.write(content) }
end
def json_read(json)
if File.exist?(json)
file = File.read(json)
data_hash = JSON.parse(file)
puts "Json content: #{data_hash}"
else
msg = 'JSON file not found'
UI.messagebox(msg, MB_OK)
end
end
# # #
end
DeveloperName::PluginName::Main.new
end
end

How to render all Jekyll pages with a different layout?

I'm trying to create a Jekyll plugin, which should go through all posts and render them with a different layout. Can't figure out how to do that. That's what I have so far:
module Jekyll
class MyGenerator < Generator
priority :low
def generate(site)
site.posts.docs.each do |doc|
page = Page.new(site, site.source, File.dirname(doc.relative_path), doc.basename)
page.do_layout(
site.site_payload,
'post' => Layout.new(site, site.source, '_layouts/my.html')
)
page.write(?)
site.pages << page
end
end
end
end
This code doesn't work.
In my code below, I'm rendering all my pages a second time with the null layout. The resulting files all have the suffix "_BARE"
module Jekyll
class BareHtml < Page
def initialize(site, base, dest_dir, src_dir, page)
#site = site
#base = base
#dir = dest_dir
#dest_dir = dest_dir
#dest_name = page.basename
file_name = "#{page.basename}_BARE.html"
self.process(file_name)
self.read_yaml(base, page.path)
self.data['layout'] = nil ### <-- set the layout name here
end
end
class BareHtmlGenerator < Generator
safe true
priority :low
def generate(site)
# Converter for .md > .html
converter = site.find_converter_instance(Jekyll::Converters::Markdown)
dest = site.dest
src = site.source
# Create destination path
FileUtils.mkpath(dest) unless File.exists?(dest)
site_pages = site.pages.dup
site_pages.each do |page|
bare = BareHtml.new(site, site.source, dest, src, page)
bare.content = converter.convert(bare.content)
bare.render(site.layouts, site.site_payload)
bare.write(site.dest)
site.pages << bare
end
end
end
end

how to pass content to jekyll default converter after custom conversion?

I am trying to write a jekyll plugin which do something on markdown files first and passing the content back to the default converter
For example,
module Jekyll
class RMarkdownConverter < Converter
safe :false
priority :high
def matches(ext)
ext =~ /^\.(md|markdown)$/i
end
def output_ext(ext)
".html"
end
def convert(content)
# do something with content
# then pass it back to default converter
end
end
end
Right now, the closest thing that I could get it
converter = Jekyll::Converters::Markdown::KramdownParser.new(#config)
converter.convert(content)
But all the highlighting codes are losing color...and I suspect there are other problems...
My question is:
what is a correct way to invoke the default converter?
Here's how to do it:
module Jekyll
class MyConverter < Converter
safe :false
priority :high
def matches(ext)
ext =~ /^\.(md|markdown)$/i
end
def output_ext(ext)
".html"
end
def convert(content)
# do your own thing with the content
content = my_own_thing(content)
# Now call the standard Markdown converter
site = Jekyll::Site.new(#config)
mkconverter = site.getConverterImpl(Jekyll::Converters::Markdown)
mkconverter.convert(content)
end
end
end
Basically, you were right in using Jekyll::Converters::Markdown, but you need not specify KramdownParser, as your chosen parser will be automatically chosen from Jekyll::Site when you pass #config into the constructor.

Can't get page data from Jekyll plugin

I'm trying to write a custom tag plugin for Jekyll that will output a hierarchical navigation tree of all the pages (not posts) on the site. I'm basically wanting a bunch nested <ul>'s with links (with the page title as the link text) to the pages with the current page noted by a certain CSS class.
I'm very inexperienced with ruby. I'm a PHP guy.
I figured I'd start just by trying to iterate through all the pages and output a one-dimensional list just to make sure I could at least do that. Here's what I have so far:
module Jekyll
class NavTree < Liquid::Tag
def initialize(tag_name, text, tokens)
super
end
def render(context)
site = context.registers[:site]
output = '<ul>'
site.pages.each do |page|
output += '<li>'+page.title+'</li>'
end
output += '<ul>'
output
end
end
end
Liquid::Template.register_tag('nav_tree', Jekyll::NavTree)
And I'm inserting it into my liquid template via {% nav_tree %}.
The problem is that the page variable in the code above doesn't have all the data that you'd expect. page.title is undefined and page.url is just the basename with a forward slash in front of it (e.g. for /a/b/c.html, it's just giving me /c.html).
What am I doing wrong?
Side note: I already tried doing this with pure Liquid markup, and I eventually gave up. I can easily iterate through site.pages just fine with Liquid, but I couldn't figure out a way to appropriately nest the lists.
Try:
module Jekyll
# Add accessor for directory
class Page
attr_reader :dir
end
class NavTree < Liquid::Tag
def initialize(tag_name, text, tokens)
super
end
def render(context)
site = context.registers[:site]
output = '<ul>'
site.pages.each do |page|
output += '<li>'+(page.data['title'] || page.url) +'</li>'
end
output += '<ul>'
output
end
end
end
Liquid::Template.register_tag('nav_tree', Jekyll::NavTree)
page.title is not always defined (example: atom.xml). You have to check if it is defined. Then you can take page.name or not process the entry...
def render(context)
site = context.registers[:site]
output = '<ul>'
site.pages.each do |page|
unless page.data['title'].nil?
t = page.data['title']
else
t = page.name
end
output += "<li>'+t+'</li>"
end
output += '<ul>'
output
end
Recently I faced a similar problem where the error "cannot convert nill into string" is just blowing my head. My config.yml file holds a line something like this " baseurl: /paradocs/jekyll/out/ " now thats for my local for a server i need to make that beseurl empty and the error starts to appear in build time so finally i have to made " baseurl: / " .. And that's did my job.

Resources