diff --git a/assets/javascripts/views/pages/perl.coffee b/assets/javascripts/views/pages/perl.coffee
new file mode 100644
index 00000000..4630ffe9
--- /dev/null
+++ b/assets/javascripts/views/pages/perl.coffee
@@ -0,0 +1,6 @@
+#= require views/pages/base
+
+class app.views.PerlPage extends app.views.BasePage
+ prepare: ->
+ @highlightCode @findAllByTag('pre'), 'perl'
+ return
diff --git a/assets/stylesheets/application-dark.css.scss b/assets/stylesheets/application-dark.css.scss
index dade560c..2c9148f2 100644
--- a/assets/stylesheets/application-dark.css.scss
+++ b/assets/stylesheets/application-dark.css.scss
@@ -59,6 +59,7 @@
'pages/nginx',
'pages/node',
'pages/npm',
+ 'pages/perl',
'pages/phalcon',
'pages/phaser',
'pages/php',
diff --git a/assets/stylesheets/application.css.scss b/assets/stylesheets/application.css.scss
index 37931d7d..e17817e0 100644
--- a/assets/stylesheets/application.css.scss
+++ b/assets/stylesheets/application.css.scss
@@ -59,6 +59,7 @@
'pages/nginx',
'pages/node',
'pages/npm',
+ 'pages/perl',
'pages/phalcon',
'pages/phaser',
'pages/php',
diff --git a/assets/stylesheets/pages/_perl.scss b/assets/stylesheets/pages/_perl.scss
new file mode 100644
index 00000000..98402adf
--- /dev/null
+++ b/assets/stylesheets/pages/_perl.scss
@@ -0,0 +1,12 @@
+._perl {
+
+ h2 { @extend %block-heading; }
+ h3 { @extend %block-label; }
+ h4 { @extend %block-label, %label-blue; }
+
+ .perlvar,
+ .perlfunction {
+ @extend %block-label, %label-blue;
+ }
+
+}
diff --git a/lib/docs/filters/perl/clean_html.rb b/lib/docs/filters/perl/clean_html.rb
new file mode 100644
index 00000000..017e9a8e
--- /dev/null
+++ b/lib/docs/filters/perl/clean_html.rb
@@ -0,0 +1,49 @@
+module Docs
+ class Perl
+ class CleanHtmlFilter < Filter
+ REMOVE_LIST = %w(
+ noscript
+ #recent_pages
+ #from_search
+ #page_index
+ .mod_az_list
+ )
+
+ def call
+ root_page? ? root : other
+ end
+
+ def root
+ doc.inner_html = '
Perl 5 Documentation
'
+ end
+
+ def other
+ @doc = at_css('#content_body')
+
+ css(*REMOVE_LIST).remove
+
+ css('h4').each { |node| node.name = 'h5' }
+ css('h3').each { |node| node.name = 'h4' }
+ css('h2').each { |node| node.name = 'h3' }
+ css('h1').drop(1).each { |node| node.name = 'h2' }
+
+ css('a[name] + h2', 'a[name] + h3', 'a[name] + h4', 'a[name] + h5').each do |node|
+ node['id'] = node.previous_element['name']
+ end
+
+ css('li > a[name]').each do |node|
+ node.parent['id'] = node['name']
+ end
+
+ css('pre').each do |node|
+ node.css('li').each do |li|
+ li.content = li.content + "\n"
+ end
+ node.content = node.content
+ end
+
+ doc
+ end
+ end
+ end
+end
diff --git a/lib/docs/filters/perl/entries.rb b/lib/docs/filters/perl/entries.rb
new file mode 100644
index 00000000..710f18e5
--- /dev/null
+++ b/lib/docs/filters/perl/entries.rb
@@ -0,0 +1,67 @@
+module Docs
+ class Perl
+ class EntriesFilter < Docs::EntriesFilter
+ REPLACE_TYPES = {
+ 'Platform specific' => 'Platform Specific',
+ 'Internals and C language interface' => 'Internals',
+
+ 'perlop' => 'Perl Operators',
+ 'perlvar' => 'Perl Variables',
+ 'Functions' => 'Functions'
+ }
+
+ def breadcrumbs
+ at_css('#breadcrumbs').content.split('>').each { |s| s.strip! }
+ end
+
+ def include_default_entry?
+ not slug =~ /\Aindex/ and
+ not slug =~ /perlop\z/ and
+ not slug =~ /perlvar/
+ end
+
+ def get_name
+ at_css('h1').content.strip
+ end
+
+ def get_type
+ case breadcrumbs[1]
+ when 'Language reference'
+ REPLACE_TYPES[breadcrumbs[2]] || 'Language Reference'
+ when /\ACore modules/
+ 'Core Modules'
+ else
+ REPLACE_TYPES[breadcrumbs[1]] || breadcrumbs[1]
+ end
+ end
+
+ def additional_entries
+ entries = []
+ case slug
+ when /perlop\z/
+ css('h2').each do |node|
+ name = node.content
+ id = node.previous_element['name']
+ entries << [name, id, get_type]
+ end
+
+ when /perlvar/
+ css('#content_body > ul > li > b').each do |node|
+ node['class'] = 'perlvar'
+ name = node.content
+ id = node.previous_element['name']
+ entries << [name, id, get_type]
+ end
+
+ when /functions/
+ css('#content_body > ul > li > b').each do |node|
+ node['class'] = 'perlfunction'
+ end
+
+ end
+
+ entries
+ end
+ end
+ end
+end
diff --git a/lib/docs/scrapers/perl.rb b/lib/docs/scrapers/perl.rb
new file mode 100644
index 00000000..9ca0ce70
--- /dev/null
+++ b/lib/docs/scrapers/perl.rb
@@ -0,0 +1,35 @@
+module Docs
+ class Perl < FileScraper
+ self.name = 'Perl'
+ self.type = 'perl'
+ self.release = '5.22.0'
+ self.dir = ''
+ self.base_url = 'http://perldoc.perl.org/'
+ self.root_path = 'index.html'
+ self.links = {
+ home: 'https://www.perl.org/'
+ }
+
+ html_filters.push 'perl/entries', 'perl/clean_html'
+
+ options[:skip] = %w(
+ preferences.html
+ perlartistic.html
+ perlgpl.html
+ perlhist.html
+ perltodo.html
+ perlunifaq.html
+ )
+
+ options[:skip_patterns] = [
+ /\.pdf/,
+ /delta\.html/,
+ /\Aperlfaq/
+ ]
+
+ options[:attribution] = <<-HTML
+ © 2010–2015
+ Dual Licensed under the GNU General Public License version 1+ or the Artistic License.
+ HTML
+ end
+end
diff --git a/public/icons/docs/perl/16.png b/public/icons/docs/perl/16.png
new file mode 100644
index 00000000..1c6ad84c
Binary files /dev/null and b/public/icons/docs/perl/16.png differ
diff --git a/public/icons/docs/perl/16@2x.png b/public/icons/docs/perl/16@2x.png
new file mode 100644
index 00000000..016daf7e
Binary files /dev/null and b/public/icons/docs/perl/16@2x.png differ
diff --git a/public/icons/docs/perl/SOURCE b/public/icons/docs/perl/SOURCE
new file mode 100644
index 00000000..9e2313c2
--- /dev/null
+++ b/public/icons/docs/perl/SOURCE
@@ -0,0 +1 @@
+http://www.perlfoundation.org/perl_trademark