Skip to content

Instantly share code, notes, and snippets.

@vidarh
Created November 10, 2021 15:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vidarh/4dc3d9cc66b5fe431531cdcd2bb7b0f7 to your computer and use it in GitHub Desktop.
Save vidarh/4dc3d9cc66b5fe431531cdcd2bb7b0f7 to your computer and use it in GitHub Desktop.
Prototype loader for GtkSourceView themes into Rouge
#
# # Theme loader
#
# Tries to load different types of themes
#
require 'nokogiri'
module ThemeLoader
include Rouge::Token::Tokens
THEME_PATHS=[
"/usr/share/gtksourceview-3.0/styles/*.xml"
]
# Mapping of GTK source view mappings.
GTKMAPPING = {
"def:string" => Literal::String,
"def:constant" => Literal,
"def:number" => Literal::Number,
"def:variable" => Name::Variable,
"def:keyword" => Keyword,
"def:statement" => Keyword,
"def:comment" => Comment,
"def:type" => Name::Class,
"def:identifier" => Name::Builtin,
}
def self.load!
THEME_PATHS.each do |path|
Dir[path].each do |theme|
ThemeLoader.load(theme)
end
end
end
def self.load(theme)
xml = Nokogiri.XML(File.read(theme))
theme = Class.new(Rouge::CSSTheme)
name = xml.xpath("/style-scheme").attr("id").value
theme.name(name)
xml.xpath("//color").each do |c|
theme.palette(c.attr("name").to_sym => c.attr("value").to_sym)
end
# Rouge barfs if we don't have a default style, so let's make sure
text = xml.xpath("//style[@name='text']").first
if text
theme.style(Text,
:fg => text.attr("foreground").to_sym,
:bg => text.attr("background").to_sym
)
else
theme.style(Text, :fg => "#ffffff", :underline => true)
end
xml.xpath("//style").each do |node|
name = node.attr("name")
rougetype = GTKMAPPING[name]
fg = node.attr("foreground")&.to_sym
opts = {}
opts[:fg] = fg if fg
opts[:italic] = true if node.attr("italic")&.to_s == "true"
opts[:bold] = true if node.attr("bold").to_s == "true"
theme.style(rougetype, opts)
end
end
end
T def self.load(theme)
xml = Nokogiri.XML(File.read(theme))
theme = Class.new(Rouge::CSSTheme)
name = xml.xpath("/style-scheme").attr("id").value
theme.name(name)
xml.xpath("//color").each do |c|
theme.palette(c.attr("name").to_sym => c.attr("value").to_sym)
end
# Rouge barfs if we don't have a default style, so let's make sure
text = xml.xpath("//style[@name='text']").first
if text
theme.style(Text,
:fg => text.attr("foreground").to_sym,
:bg => text.attr("background").to_sym
)
else
theme.style(Text, :fg => "#ffffff", :underline => true)
end
xml.xpath("//style").each do |node|
name = node.attr("name")
rougetype = GTKMAPPING[name]
fg = node.attr("foreground")&.to_sym
opts = {}
opts[:fg] = fg if fg
opts[:italic] = true if node.attr("italic")&.to_s == "true"
opts[:bold] = true if node.attr("bold").to_s == "true"
theme.style(rougetype, opts)
end
end
end
ThemeLoader.load!
@vidarh
Copy link
Author

vidarh commented Nov 5, 2023

A newer / better version of this is here:
https://github.com/vidarh/rouge-gtk_theme_loader

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment