* Add toc (table of contents) plugin.
parent
e5b323a633
commit
e16746a52f
|
@ -21,6 +21,8 @@ sub import { #{{{
|
||||||
call => \&htmlize);
|
call => \&htmlize);
|
||||||
IkiWiki::hook(type => "sanitize", id => "skeleton",
|
IkiWiki::hook(type => "sanitize", id => "skeleton",
|
||||||
call => \&sanitize);
|
call => \&sanitize);
|
||||||
|
IkiWiki::hook(type => "format", id => "skeleton",
|
||||||
|
call => \&format);
|
||||||
IkiWiki::hook(type => "pagetemplate", id => "skeleton",
|
IkiWiki::hook(type => "pagetemplate", id => "skeleton",
|
||||||
call => \&pagetemplate);
|
call => \&pagetemplate);
|
||||||
IkiWiki::hook(type => "delete", id => "skeleton",
|
IkiWiki::hook(type => "delete", id => "skeleton",
|
||||||
|
@ -71,6 +73,14 @@ sub sanitize ($) { #{{{
|
||||||
return $content;
|
return $content;
|
||||||
} # }}}
|
} # }}}
|
||||||
|
|
||||||
|
sub format ($) { #{{{
|
||||||
|
my $content=shift;
|
||||||
|
|
||||||
|
IkiWiki::debug("skeleton plugin running as a formatter");
|
||||||
|
|
||||||
|
return $content;
|
||||||
|
} # }}}
|
||||||
|
|
||||||
sub pagetemplate (@) { #{{{
|
sub pagetemplate (@) { #{{{
|
||||||
my %params=@_;
|
my %params=@_;
|
||||||
my $page=$params{page};
|
my $page=$params{page};
|
||||||
|
|
|
@ -0,0 +1,116 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
# Table Of Contents generator
|
||||||
|
package IkiWiki::Plugin::toc;
|
||||||
|
|
||||||
|
use warnings;
|
||||||
|
use strict;
|
||||||
|
use IkiWiki;
|
||||||
|
use HTML::Parser;
|
||||||
|
|
||||||
|
sub import { #{{{
|
||||||
|
IkiWiki::hook(type => "preprocess", id => "toc",
|
||||||
|
call => \&preprocess);
|
||||||
|
IkiWiki::hook(type => "format", id => "toc",
|
||||||
|
call => \&format);
|
||||||
|
} # }}}
|
||||||
|
|
||||||
|
my @tocs;
|
||||||
|
|
||||||
|
sub preprocess (@) { #{{{
|
||||||
|
my %params=@_;
|
||||||
|
|
||||||
|
$params{levels}=1 unless exists $params{levels};
|
||||||
|
|
||||||
|
# It's too early to generate the toc here, so just record the
|
||||||
|
# info.
|
||||||
|
push @tocs, \%params;
|
||||||
|
|
||||||
|
return "\n[[toc $#tocs]]\n";
|
||||||
|
} # }}}
|
||||||
|
|
||||||
|
sub format ($) { #{{{
|
||||||
|
my $content=shift;
|
||||||
|
|
||||||
|
return $content unless @tocs && $content=~/\[\[toc (\d+)\]\]/ && $#tocs >= $1;
|
||||||
|
my $id=$1;
|
||||||
|
my %params=%{$tocs[$id]};
|
||||||
|
|
||||||
|
my $p=HTML::Parser->new(api_version => 3);
|
||||||
|
my $page="";
|
||||||
|
my $index="";
|
||||||
|
my %anchors;
|
||||||
|
my $curlevel;
|
||||||
|
my $startlevel=0;
|
||||||
|
my $liststarted=0;
|
||||||
|
my $indent=sub { "\t" x $curlevel };
|
||||||
|
$p->handler(start => sub {
|
||||||
|
my $tagname=shift;
|
||||||
|
my $text=shift;
|
||||||
|
if ($tagname =~ /^h(\d+)$/i) {
|
||||||
|
my $level=$1;
|
||||||
|
my $anchor="index".++$anchors{$level}."h$level";
|
||||||
|
$page.="$text<a name=\"$anchor\" />";
|
||||||
|
|
||||||
|
# Take the first header level seen as the topmost level,
|
||||||
|
# even if there are higher levels seen later on.
|
||||||
|
if (! $startlevel) {
|
||||||
|
$startlevel=$level;
|
||||||
|
$curlevel=$startlevel-1;
|
||||||
|
}
|
||||||
|
elsif ($level < $startlevel) {
|
||||||
|
$level=$startlevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
return if $level - $startlevel >= $params{levels};
|
||||||
|
|
||||||
|
if ($level > $curlevel) {
|
||||||
|
while ($level > $curlevel + 1) {
|
||||||
|
$index.=&$indent."<ol>\n";
|
||||||
|
$curlevel++;
|
||||||
|
$index.=&$indent."<li class=\"L$curlevel\">\n";
|
||||||
|
}
|
||||||
|
$index.=&$indent."<ol>\n";
|
||||||
|
$curlevel=$level;
|
||||||
|
$liststarted=1;
|
||||||
|
}
|
||||||
|
elsif ($level < $curlevel) {
|
||||||
|
while ($level < $curlevel) {
|
||||||
|
$index.=&$indent."</li>\n" if $curlevel;
|
||||||
|
$curlevel--;
|
||||||
|
$index.=&$indent."</ol>\n";
|
||||||
|
}
|
||||||
|
$liststarted=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$p->handler(text => sub {
|
||||||
|
$page.=join("", @_);
|
||||||
|
$index.=&$indent."</li>\n" unless $liststarted;
|
||||||
|
$liststarted=0;
|
||||||
|
$index.=&$indent."<li class=\"L$curlevel\">".
|
||||||
|
"<a href=\"#$anchor\">".
|
||||||
|
join("", @_).
|
||||||
|
"</a>\n";
|
||||||
|
$p->handler(text => undef);
|
||||||
|
}, "dtext");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$page.=$text;
|
||||||
|
}
|
||||||
|
}, "tagname, text");
|
||||||
|
$p->handler(default => sub { $page.=join("", @_) }, "text");
|
||||||
|
$p->parse($content);
|
||||||
|
$p->eof;
|
||||||
|
|
||||||
|
while ($startlevel && $curlevel >= $startlevel) {
|
||||||
|
$index.=&$indent."</li>\n" if $curlevel;
|
||||||
|
$curlevel--;
|
||||||
|
$index.=&$indent."</ol>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Ignore cruft around the toc marker, probably <p> tags added by
|
||||||
|
# markdown which shouldn't appear in a list anyway.
|
||||||
|
$page=~s/\n.*\[\[toc $id\]\].*\n/$index/;
|
||||||
|
return $page;
|
||||||
|
}
|
||||||
|
|
||||||
|
1
|
|
@ -24,7 +24,7 @@ extra_build:
|
||||||
--plugin=orphans --plugin=haiku --plugin=meta \
|
--plugin=orphans --plugin=haiku --plugin=meta \
|
||||||
--plugin=tag --plugin=polygen --plugin=pagestats \
|
--plugin=tag --plugin=polygen --plugin=pagestats \
|
||||||
--plugin=fortune --plugin=aggregate --plugin=map \
|
--plugin=fortune --plugin=aggregate --plugin=map \
|
||||||
--plugin=template
|
--plugin=template --plugin=toc
|
||||||
./mdwn2man ikiwiki 1 doc/usage.mdwn > ikiwiki.man
|
./mdwn2man ikiwiki 1 doc/usage.mdwn > ikiwiki.man
|
||||||
./mdwn2man ikiwiki-mass-rebuild 8 doc/ikiwiki-mass-rebuild.mdwn > ikiwiki-mass-rebuild.man
|
./mdwn2man ikiwiki-mass-rebuild 8 doc/ikiwiki-mass-rebuild.mdwn > ikiwiki-mass-rebuild.man
|
||||||
|
|
||||||
|
|
|
@ -40,8 +40,9 @@ ikiwiki (1.22) UNRELEASED; urgency=low
|
||||||
* Factor out the cgi header printing code into a new function.
|
* Factor out the cgi header printing code into a new function.
|
||||||
* Fix preferences page on anonok wikis; still need to sign in to get
|
* Fix preferences page on anonok wikis; still need to sign in to get
|
||||||
to the preferences page.
|
to the preferences page.
|
||||||
|
* Add toc (table of contents) plugin.
|
||||||
|
|
||||||
-- Joey Hess <joeyh@debian.org> Sun, 27 Aug 2006 16:17:21 -0400
|
-- Joey Hess <joeyh@debian.org> Mon, 28 Aug 2006 02:31:56 -0400
|
||||||
|
|
||||||
ikiwiki (1.21) unstable; urgency=low
|
ikiwiki (1.21) unstable; urgency=low
|
||||||
|
|
||||||
|
|
|
@ -1,155 +1,152 @@
|
||||||
Some of ikiwiki's features:
|
An overview of some of ikiwiki's features:
|
||||||
|
[[toc ]]
|
||||||
|
|
||||||
* Uses a real RCS
|
## Uses a real RCS
|
||||||
|
|
||||||
Rather than implement its own system for storing page histories etc,
|
Rather than implement its own system for storing page histories etc,
|
||||||
ikiwiki uses a real RCS. This isn't because we're lazy, it's because a
|
ikiwiki uses a real RCS. This isn't because we're lazy, it's because a
|
||||||
real RCS is a good thing to have, and there are advantages to using one
|
real RCS is a good thing to have, and there are advantages to using one
|
||||||
that are not possible with a standard wiki.
|
that are not possible with a standard wiki.
|
||||||
|
|
||||||
Instead of editing pages in a stupid web form, you can use vim and commit
|
Instead of editing pages in a stupid web form, you can use vim and commit
|
||||||
changes via svn. Or work disconnected using svk and push your changes out
|
changes via svn. Or work disconnected using svk and push your changes out
|
||||||
when you come online. Or use git to work in a distributed fashion all the
|
when you come online. Or use git to work in a distributed fashion all the
|
||||||
time. (It's also possible to [[plugins/write]] a plugin to support other
|
time. (It's also possible to [[plugins/write]] a plugin to support other
|
||||||
systems.)
|
systems.)
|
||||||
|
|
||||||
ikiwiki can be run from a [[post-commit]] hook to update your wiki
|
ikiwiki can be run from a [[post-commit]] hook to update your wiki
|
||||||
immediately whenever you commit.
|
immediately whenever you commit.
|
||||||
|
|
||||||
Note that ikiwiki does not require a RCS to function. If you want to
|
Note that ikiwiki does not require a RCS to function. If you want to
|
||||||
run a simple wiki without page history, it can do that too.
|
run a simple wiki without page history, it can do that too.
|
||||||
|
|
||||||
* Supports many markup languages
|
## Supports many markup languages
|
||||||
|
|
||||||
By default, pages in the wiki are written using the [[MarkDown]] format.
|
By default, pages in the wiki are written using the [[MarkDown]] format.
|
||||||
Any page with a filename ending in ".mdwn" is converted from markdown to html
|
Any page with a filename ending in ".mdwn" is converted from markdown to html
|
||||||
by ikiwiki. Markdown understands text formatted as it would be in an email,
|
by ikiwiki. Markdown understands text formatted as it would be in an email,
|
||||||
and is quite smart about converting it to html. The only additional markup
|
and is quite smart about converting it to html. The only additional markup
|
||||||
provided by ikiwiki on top of regular markdown is the [[WikiLink]] and
|
provided by ikiwiki on top of regular markdown is the [[WikiLink]] and
|
||||||
[[PreprocessorDirective]].
|
[[PreprocessorDirective]].
|
||||||
|
|
||||||
If you prefer to use some other markup language, ikiwiki allows others to
|
If you prefer to use some other markup language, ikiwiki allows others to
|
||||||
easily be added by [[plugins]]. For example it also supports traditional
|
easily be added by [[plugins]]. For example it also supports traditional
|
||||||
[[plugins/WikiText]] formatted pages, pages written as pure
|
[[plugins/WikiText]] formatted pages, pages written as pure
|
||||||
[[plugins/HTML]], or pages written in [[reStructuredText|plugins/rst]].
|
[[plugins/HTML]], or pages written in [[reStructuredText|plugins/rst]].
|
||||||
|
|
||||||
* support for other file types
|
## support for other file types
|
||||||
|
|
||||||
ikiwiki also supports files of any other type, including plain text,
|
ikiwiki also supports files of any other type, including plain text,
|
||||||
images, etc. These are not converted to wiki pages, they are just copied
|
images, etc. These are not converted to wiki pages, they are just copied
|
||||||
unchanged by ikiwiki as it builds your wiki. So you can check in an image,
|
unchanged by ikiwiki as it builds your wiki. So you can check in an image,
|
||||||
program, or other special file and link to it from your wiki pages.
|
program, or other special file and link to it from your wiki pages.
|
||||||
|
|
||||||
* Fast compiler
|
## Fast compiler
|
||||||
|
|
||||||
ikiwiki is fast and smart about updating a wiki, it only builds pages
|
ikiwiki is fast and smart about updating a wiki, it only builds pages
|
||||||
that have changed (and tracks things like creation of new pages and links
|
that have changed (and tracks things like creation of new pages and links
|
||||||
that can indirectly cause a page to need a rebuild)
|
that can indirectly cause a page to need a rebuild)
|
||||||
|
|
||||||
* [[blogging|blog]]
|
## [[blogging|blog]]
|
||||||
|
|
||||||
You can turn any page in the wiki into a [[blog]]. Pages matching a
|
You can turn any page in the wiki into a [[blog]]. Pages matching a
|
||||||
specified [[PageSpec]] will be displayed as a weblog within the blog
|
specified [[PageSpec]] will be displayed as a weblog within the blog
|
||||||
page. And an RSS feed can be generated to follow the blog.
|
page. And an RSS feed can be generated to follow the blog.
|
||||||
|
|
||||||
Ikiwiki's own [[TODO]], [[news]], and [[plugins]] pages are good examples
|
Ikiwiki's own [[TODO]], [[news]], and [[plugins]] pages are good examples
|
||||||
of some of the flexible ways that this can be used.
|
of some of the flexible ways that this can be used.
|
||||||
|
|
||||||
Ikiwiki can also [[plugins/aggregate]] external blogs, feeding them into
|
Ikiwiki can also [[plugins/aggregate]] external blogs, feeding them into
|
||||||
the wiki. This can be used to create a Planet type site that aggregates
|
the wiki. This can be used to create a Planet type site that aggregates
|
||||||
interesting feeds.
|
interesting feeds.
|
||||||
|
|
||||||
* [[tags]]
|
## [[tags]]
|
||||||
|
|
||||||
You can tag pages and use these tags in various ways. Tags will show
|
You can tag pages and use these tags in various ways. Tags will show
|
||||||
up in the ways you'd expect, like at the bottom of pages, in blogs, and
|
up in the ways you'd expect, like at the bottom of pages, in blogs, and
|
||||||
in rss feeds.
|
in rss feeds.
|
||||||
|
|
||||||
* valid html and css
|
## valid html and css
|
||||||
|
|
||||||
ikiwiki aims to produce
|
ikiwiki aims to produce
|
||||||
[valid XHTML 1.0](http://validator.w3.org/check?url=referer).
|
[valid XHTML 1.0](http://validator.w3.org/check?url=referer).
|
||||||
ikiwiki generates html using [[templates]], and uses css, so you can
|
ikiwiki generates html using [[templates]], and uses css, so you can
|
||||||
change the look and layout of all pages in any way you would like.
|
change the look and layout of all pages in any way you would like.
|
||||||
|
|
||||||
* [[SubPages|SubPage]]
|
## [[SubPages|SubPage]]
|
||||||
|
|
||||||
Arbitrarily deep hierarchies of pages with fairly simple and useful
|
Arbitrarily deep hierarchies of pages with fairly simple and useful
|
||||||
[[SubPage/LinkingRules]]
|
[[SubPage/LinkingRules]]
|
||||||
|
|
||||||
* [[BackLinks]]
|
## [[BackLinks]]
|
||||||
|
|
||||||
Automatically included on pages. Rather faster than eg MoinMoin and
|
Automatically included on pages. Rather faster than eg MoinMoin and
|
||||||
always there to help with navigation.
|
always there to help with navigation.
|
||||||
|
|
||||||
* [[PageHistory]]
|
## [[PageHistory]]
|
||||||
|
|
||||||
Well, sorta. Rather than implementing YA history browser, it can link to
|
Well, sorta. Rather than implementing YA history browser, it can link to
|
||||||
[[ViewCVS]] or the like to browse the history of a wiki page.
|
[[ViewCVS]] or the like to browse the history of a wiki page.
|
||||||
|
|
||||||
* [[RecentChanges]], editing pages in a web browser
|
## [[RecentChanges]], editing pages in a web browser
|
||||||
|
|
||||||
Nearly the definition of a wiki, although perhaps ikiwiki challenges how
|
Nearly the definition of a wiki, although perhaps ikiwiki challenges how
|
||||||
much of that web gunk a wiki really needs. These features are optional
|
much of that web gunk a wiki really needs. These features are optional
|
||||||
and can be enabled by enabling [[CGI]].
|
and can be enabled by enabling [[CGI]].
|
||||||
|
|
||||||
* User registration
|
## User registration
|
||||||
|
|
||||||
Can optionally be configured to allow only registered users to post
|
Can optionally be configured to allow only registered users to post
|
||||||
pages; online user registration form, etc.
|
pages; online user registration form, etc.
|
||||||
|
|
||||||
* Discussion pages
|
## Discussion pages
|
||||||
|
|
||||||
Thanks to subpages, every page can easily and automatically have a
|
Thanks to subpages, every page can easily and automatically have a
|
||||||
/Discussion subpage. By default, these links are included in the
|
/Discussion subpage. By default, these links are included in the
|
||||||
[[templates]] for each page.
|
[[templates]] for each page.
|
||||||
|
|
||||||
* Smart merging and conflict resolution in your web browser
|
## Smart merging and conflict resolution in your web browser
|
||||||
|
|
||||||
Since it uses a real RCS, ikiwiki takes advantage of its smart merging to
|
Since it uses a real RCS, ikiwiki takes advantage of its smart merging to
|
||||||
avoid any conflicts when two people edit different parts of the same page
|
avoid any conflicts when two people edit different parts of the same page
|
||||||
at the same time. No annoying warnings about other editors, or locking,
|
at the same time. No annoying warnings about other editors, or locking,
|
||||||
etc, instead the other person's changes will be automatically merged with
|
etc, instead the other person's changes will be automatically merged with
|
||||||
yours when you commit.
|
yours when you commit.
|
||||||
|
|
||||||
In the rare cases where automatic merging fails due to the same part of a
|
In the rare cases where automatic merging fails due to the same part of a
|
||||||
page being concurrently edited, regular commit conflict markers are
|
page being concurrently edited, regular commit conflict markers are
|
||||||
shown in the file to resolve the conflict, so if you're already familiar
|
shown in the file to resolve the conflict, so if you're already familiar
|
||||||
with that there's no new commit marker syntax to learn.
|
with that there's no new commit marker syntax to learn.
|
||||||
|
|
||||||
* page locking
|
## page locking
|
||||||
|
|
||||||
Wiki admins can lock pages so that only other admins can edit them.
|
Wiki admins can lock pages so that only other admins can edit them.
|
||||||
|
|
||||||
* Full text search
|
## Full text search
|
||||||
|
|
||||||
ikiwiki can use the [[HyperEstraier]] search engine to add powerful
|
ikiwiki can use the [[HyperEstraier]] search engine to add powerful
|
||||||
full text search capabilities to your wiki.
|
full text search capabilities to your wiki.
|
||||||
|
|
||||||
* Commit mails
|
## Commit mails
|
||||||
|
|
||||||
ikiwiki can be configured to send you commit mails with diffs of changes
|
ikiwiki can be configured to send you commit mails with diffs of changes
|
||||||
to selected pages.
|
to selected pages.
|
||||||
|
|
||||||
* [[Plugins]]
|
## [[Plugins]]
|
||||||
|
|
||||||
Plugins can be used to add additional features to ikiwiki. The interface
|
Plugins can be used to add additional features to ikiwiki. The interface
|
||||||
is quite flexible, allowing plugins to implement additional markup
|
is quite flexible, allowing plugins to implement additional markup
|
||||||
languages, register [[PreProcessorDirective]]s, hook into [[CGI]] mode,
|
languages, register [[PreProcessorDirective]]s, hook into [[CGI]] mode,
|
||||||
and more. Most of ikiwiki's features are actually provided by plugins.
|
and more. Most of ikiwiki's features are actually provided by plugins.
|
||||||
Ikiwiki's backend RCS support is also pluggable, so support for new
|
Ikiwiki's backend RCS support is also pluggable, so support for new
|
||||||
revision control systems can be added to ikiwiki.
|
revision control systems can be added to ikiwiki.
|
||||||
|
|
||||||
* [[todo/utf8]]
|
## [[todo/utf8]]
|
||||||
|
|
||||||
After rather a lot of fiddling, we think that ikiwiki correctly and fully
|
After rather a lot of fiddling, we think that ikiwiki correctly and fully
|
||||||
supports utf8 everywhere.
|
supports utf8 everywhere.
|
||||||
|
|
||||||
* [[w3mmode]]
|
## [[w3mmode]]
|
||||||
|
|
||||||
Can be set up so that w3m can be used to browse a wiki and edit pages
|
Can be set up so that w3m can be used to browse a wiki and edit pages
|
||||||
without using a web server.
|
without using a web server.
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
It also has some [[TODO]] items and [[Bugs]].
|
|
||||||
|
|
|
@ -83,7 +83,7 @@ use IkiWiki::Setup::Standard {
|
||||||
# To add plugins, list them here.
|
# To add plugins, list them here.
|
||||||
#add_plugins => [qw{meta tag pagecount brokenlinks search smiley
|
#add_plugins => [qw{meta tag pagecount brokenlinks search smiley
|
||||||
# wikitext camelcase pagestats htmltidy fortune
|
# wikitext camelcase pagestats htmltidy fortune
|
||||||
# sidebar map rst}],
|
# sidebar map rst toc}],
|
||||||
# If you want to disable any of the default plugins, list them here.
|
# If you want to disable any of the default plugins, list them here.
|
||||||
#disable_plugins => [qw{inline htmlscrubber}],
|
#disable_plugins => [qw{inline htmlscrubber}],
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
[[template id=plugin name=toc included=1 author="Joey Hess"]]
|
||||||
|
[[tag type/chrome]]
|
||||||
|
|
||||||
|
Add a table of contents be to a page:
|
||||||
|
|
||||||
|
\[[toc ]]
|
||||||
|
|
||||||
|
The table of contents will be automatically generated based on the
|
||||||
|
headers of the page. By default only the largest headers present on the
|
||||||
|
page will be shown; to control how many levels of headers are shown, use
|
||||||
|
the `levels` parameter:
|
||||||
|
|
||||||
|
\[[toc levels=2]]
|
|
@ -6,6 +6,8 @@ security issues with this program than with cat(1). If, however, you let
|
||||||
others edit pages in your wiki, then some possible security issues do need
|
others edit pages in your wiki, then some possible security issues do need
|
||||||
to be kept in mind.
|
to be kept in mind.
|
||||||
|
|
||||||
|
[[toc levels=2]]
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
# Probable holes
|
# Probable holes
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
Might be nice to support automatically generating an index based on headers
|
Might be nice to support automatically generating an index based on headers
|
||||||
in a page, for long pages. This could be done as a sanitize hook that
|
in a page, for long pages. This could be done as a sanitize hook that
|
||||||
parsed the html, with a preprocessordirective that controlled it.
|
parsed the html, with a preprocessordirective that controlled it.
|
||||||
|
|
||||||
|
[[todo/done]]
|
||||||
|
|
2
t/html.t
2
t/html.t
|
@ -6,7 +6,7 @@ use Test::More;
|
||||||
my @pages;
|
my @pages;
|
||||||
|
|
||||||
BEGIN {
|
BEGIN {
|
||||||
@pages=qw(index todo features news plugins/map);
|
@pages=qw(index todo features news plugins/map security);
|
||||||
if (! -x "/usr/bin/validate") {
|
if (! -x "/usr/bin/validate") {
|
||||||
plan skip_all => "/usr/bin/validate html validator not present";
|
plan skip_all => "/usr/bin/validate html validator not present";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue