From: Pavan Kumar Sunkara <pavan.sss1991@gmail.com>
To: git@vger.kernel.org, jnareb@gmail.com, chriscool@tuxfamily.org,
pasky@ucw.cz
Cc: Pavan Kumar Sunkara <pavan.sss1991@gmail.com>
Subject: [RFC/PATCH 4/4] gitweb: Create Gitweb::HTML::String module
Date: Tue, 8 Jun 2010 02:20:44 +0530 [thread overview]
Message-ID: <1275943844-24991-4-git-send-email-pavan.sss1991@gmail.com> (raw)
In-Reply-To: <1275943844-24991-1-git-send-email-pavan.sss1991@gmail.com>
Create Gitweb::HTML::String module in 'gitweb/lib/Gitweb/HTML/String.pm'
to store all the subs involving string manipulation and those returning
short strings regarding gitweb.perl.
Subroutines moved:
chop_str
chop_and_escape_str
S_ISGITLINK
mode_str
file_type
file_type_long
age_class
age_string
Import Gitweb::HTML:String into Gitweb::HTML module.
Updare gitweb/Makefile to install this module alongside gitweb.
Signed-off-by: Pavan Kumar Sunkara <pavan.sss1991@gmail.com>
---
gitweb/Makefile | 1 +
gitweb/gitweb.perl | 213 ----------------------------------
gitweb/lib/Gitweb/HTML.pm | 4 +-
gitweb/lib/Gitweb/HTML/String.pm | 232 ++++++++++++++++++++++++++++++++++++++
4 files changed, 236 insertions(+), 214 deletions(-)
create mode 100644 gitweb/lib/Gitweb/HTML/String.pm
diff --git a/gitweb/Makefile b/gitweb/Makefile
index 5e44ace..9b4b718 100644
--- a/gitweb/Makefile
+++ b/gitweb/Makefile
@@ -119,6 +119,7 @@ GITWEB_LIB_GITWEB += lib/Gitweb/Git.pm
GITWEB_LIB_GITWEB += lib/Gitweb/HTML.pm
# Files: gitweb/lib/Gitweb/HTML
GITWEB_LIB_GITWEB_HTML += lib/Gitweb/HTML/Link.pm
+GITWEB_LIB_GITWEB_HTML += lib/Gitweb/HTML/String.pm
GITWEB_REPLACE = \
-e 's|++GIT_VERSION++|$(GIT_VERSION)|g' \
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 12646c0..f2fdcae 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -582,219 +582,6 @@ sub project_in_list {
}
## ----------------------------------------------------------------------
-## HTML aware string manipulation
-
-# Try to chop given string on a word boundary between position
-# $len and $len+$add_len. If there is no word boundary there,
-# chop at $len+$add_len. Do not chop if chopped part plus ellipsis
-# (marking chopped part) would be longer than given string.
-sub chop_str {
- my $str = shift;
- my $len = shift;
- my $add_len = shift || 10;
- my $where = shift || 'right'; # 'left' | 'center' | 'right'
-
- # Make sure perl knows it is utf8 encoded so we don't
- # cut in the middle of a utf8 multibyte char.
- $str = to_utf8($str);
-
- # allow only $len chars, but don't cut a word if it would fit in $add_len
- # if it doesn't fit, cut it if it's still longer than the dots we would add
- # remove chopped character entities entirely
-
- # when chopping in the middle, distribute $len into left and right part
- # return early if chopping wouldn't make string shorter
- if ($where eq 'center') {
- return $str if ($len + 5 >= length($str)); # filler is length 5
- $len = int($len/2);
- } else {
- return $str if ($len + 4 >= length($str)); # filler is length 4
- }
-
- # regexps: ending and beginning with word part up to $add_len
- my $endre = qr/.{$len}\w{0,$add_len}/;
- my $begre = qr/\w{0,$add_len}.{$len}/;
-
- if ($where eq 'left') {
- $str =~ m/^(.*?)($begre)$/;
- my ($lead, $body) = ($1, $2);
- if (length($lead) > 4) {
- $lead = " ...";
- }
- return "$lead$body";
-
- } elsif ($where eq 'center') {
- $str =~ m/^($endre)(.*)$/;
- my ($left, $str) = ($1, $2);
- $str =~ m/^(.*?)($begre)$/;
- my ($mid, $right) = ($1, $2);
- if (length($mid) > 5) {
- $mid = " ... ";
- }
- return "$left$mid$right";
-
- } else {
- $str =~ m/^($endre)(.*)$/;
- my $body = $1;
- my $tail = $2;
- if (length($tail) > 4) {
- $tail = "... ";
- }
- return "$body$tail";
- }
-}
-
-# takes the same arguments as chop_str, but also wraps a <span> around the
-# result with a title attribute if it does get chopped. Additionally, the
-# string is HTML-escaped.
-sub chop_and_escape_str {
- my ($str) = @_;
-
- my $chopped = chop_str(@_);
- if ($chopped eq $str) {
- return esc_html($chopped);
- } else {
- $str =~ s/[[:cntrl:]]/?/g;
- return $cgi->span({-title=>$str}, esc_html($chopped));
- }
-}
-
-## ----------------------------------------------------------------------
-## functions returning short strings
-
-# CSS class for given age value (in seconds)
-sub age_class {
- my $age = shift;
-
- if (!defined $age) {
- return "noage";
- } elsif ($age < 60*60*2) {
- return "age0";
- } elsif ($age < 60*60*24*2) {
- return "age1";
- } else {
- return "age2";
- }
-}
-
-# convert age in seconds to "nn units ago" string
-sub age_string {
- my $age = shift;
- my $age_str;
-
- if ($age > 60*60*24*365*2) {
- $age_str = (int $age/60/60/24/365);
- $age_str .= " years ago";
- } elsif ($age > 60*60*24*(365/12)*2) {
- $age_str = int $age/60/60/24/(365/12);
- $age_str .= " months ago";
- } elsif ($age > 60*60*24*7*2) {
- $age_str = int $age/60/60/24/7;
- $age_str .= " weeks ago";
- } elsif ($age > 60*60*24*2) {
- $age_str = int $age/60/60/24;
- $age_str .= " days ago";
- } elsif ($age > 60*60*2) {
- $age_str = int $age/60/60;
- $age_str .= " hours ago";
- } elsif ($age > 60*2) {
- $age_str = int $age/60;
- $age_str .= " min ago";
- } elsif ($age > 2) {
- $age_str = int $age;
- $age_str .= " sec ago";
- } else {
- $age_str .= " right now";
- }
- return $age_str;
-}
-
-use constant {
- S_IFINVALID => 0030000,
- S_IFGITLINK => 0160000,
-};
-
-# submodule/subproject, a commit object reference
-sub S_ISGITLINK {
- my $mode = shift;
-
- return (($mode & S_IFMT) == S_IFGITLINK)
-}
-
-# convert file mode in octal to symbolic file mode string
-sub mode_str {
- my $mode = oct shift;
-
- if (S_ISGITLINK($mode)) {
- return 'm---------';
- } elsif (S_ISDIR($mode & S_IFMT)) {
- return 'drwxr-xr-x';
- } elsif (S_ISLNK($mode)) {
- return 'lrwxrwxrwx';
- } elsif (S_ISREG($mode)) {
- # git cares only about the executable bit
- if ($mode & S_IXUSR) {
- return '-rwxr-xr-x';
- } else {
- return '-rw-r--r--';
- };
- } else {
- return '----------';
- }
-}
-
-# convert file mode in octal to file type string
-sub file_type {
- my $mode = shift;
-
- if ($mode !~ m/^[0-7]+$/) {
- return $mode;
- } else {
- $mode = oct $mode;
- }
-
- if (S_ISGITLINK($mode)) {
- return "submodule";
- } elsif (S_ISDIR($mode & S_IFMT)) {
- return "directory";
- } elsif (S_ISLNK($mode)) {
- return "symlink";
- } elsif (S_ISREG($mode)) {
- return "file";
- } else {
- return "unknown";
- }
-}
-
-# convert file mode in octal to file type description string
-sub file_type_long {
- my $mode = shift;
-
- if ($mode !~ m/^[0-7]+$/) {
- return $mode;
- } else {
- $mode = oct $mode;
- }
-
- if (S_ISGITLINK($mode)) {
- return "submodule";
- } elsif (S_ISDIR($mode & S_IFMT)) {
- return "directory";
- } elsif (S_ISLNK($mode)) {
- return "symlink";
- } elsif (S_ISREG($mode)) {
- if ($mode & S_IXUSR) {
- return "executable";
- } else {
- return "file";
- };
- } else {
- return "unknown";
- }
-}
-
-
-## ----------------------------------------------------------------------
## functions returning short HTML fragments, or transforming HTML fragments
## which don't belong to other sections
diff --git a/gitweb/lib/Gitweb/HTML.pm b/gitweb/lib/Gitweb/HTML.pm
index a0a1606..49a3b54 100644
--- a/gitweb/lib/Gitweb/HTML.pm
+++ b/gitweb/lib/Gitweb/HTML.pm
@@ -10,8 +10,10 @@ use strict;
use warnings;
use Exporter qw(import);
-our @EXPORT = qw(href);
+our @EXPORT = qw(href chop_str chop_and_escape_str age_class age_string mode_str
+ file_type file_type_long);
use Gitweb::HTML::Link;
+use Gitweb::HTML::String;
1;
diff --git a/gitweb/lib/Gitweb/HTML/String.pm b/gitweb/lib/Gitweb/HTML/String.pm
new file mode 100644
index 0000000..a8f6417
--- /dev/null
+++ b/gitweb/lib/Gitweb/HTML/String.pm
@@ -0,0 +1,232 @@
+#!/usr/bin/perl
+#
+# Gitweb::HTML::String -- gitweb's string manipulation & short string package
+#
+# This program is licensed under the GPLv2
+
+package Gitweb::HTML::String;
+
+use strict;
+use warnings;
+use Exporter qw(import);
+
+our @EXPORT = qw(chop_str chop_and_escape_str age_class age_string mode_str
+ file_type file_type_long);
+
+use Fcntl ':mode';
+use Gitweb::Request qw($cgi);
+use Gitweb::Escape qw(to_utf8 esc_html);
+
+## ----------------------------------------------------------------------
+## HTML aware string manipulation
+
+# Try to chop given string on a word boundary between position
+# $len and $len+$add_len. If there is no word boundary there,
+# chop at $len+$add_len. Do not chop if chopped part plus ellipsis
+# (marking chopped part) would be longer than given string.
+sub chop_str {
+ my $str = shift;
+ my $len = shift;
+ my $add_len = shift || 10;
+ my $where = shift || 'right'; # 'left' | 'center' | 'right'
+
+ # Make sure perl knows it is utf8 encoded so we don't
+ # cut in the middle of a utf8 multibyte char.
+ $str = to_utf8($str);
+
+ # allow only $len chars, but don't cut a word if it would fit in $add_len
+ # if it doesn't fit, cut it if it's still longer than the dots we would add
+ # remove chopped character entities entirely
+
+ # when chopping in the middle, distribute $len into left and right part
+ # return early if chopping wouldn't make string shorter
+ if ($where eq 'center') {
+ return $str if ($len + 5 >= length($str)); # filler is length 5
+ $len = int($len/2);
+ } else {
+ return $str if ($len + 4 >= length($str)); # filler is length 4
+ }
+
+ # regexps: ending and beginning with word part up to $add_len
+ my $endre = qr/.{$len}\w{0,$add_len}/;
+ my $begre = qr/\w{0,$add_len}.{$len}/;
+
+ if ($where eq 'left') {
+ $str =~ m/^(.*?)($begre)$/;
+ my ($lead, $body) = ($1, $2);
+ if (length($lead) > 4) {
+ $lead = " ...";
+ }
+ return "$lead$body";
+
+ } elsif ($where eq 'center') {
+ $str =~ m/^($endre)(.*)$/;
+ my ($left, $str) = ($1, $2);
+ $str =~ m/^(.*?)($begre)$/;
+ my ($mid, $right) = ($1, $2);
+ if (length($mid) > 5) {
+ $mid = " ... ";
+ }
+ return "$left$mid$right";
+
+ } else {
+ $str =~ m/^($endre)(.*)$/;
+ my $body = $1;
+ my $tail = $2;
+ if (length($tail) > 4) {
+ $tail = "... ";
+ }
+ return "$body$tail";
+ }
+}
+
+# takes the same arguments as chop_str, but also wraps a <span> around the
+# result with a title attribute if it does get chopped. Additionally, the
+# string is HTML-escaped.
+sub chop_and_escape_str {
+ my ($str) = @_;
+
+ my $chopped = chop_str(@_);
+ if ($chopped eq $str) {
+ return esc_html($chopped);
+ } else {
+ $str =~ s/[[:cntrl:]]/?/g;
+ return $cgi->span({-title=>$str}, esc_html($chopped));
+ }
+}
+
+## ----------------------------------------------------------------------
+## functions returning short strings
+
+# CSS class for given age value (in seconds)
+sub age_class {
+ my $age = shift;
+
+ if (!defined $age) {
+ return "noage";
+ } elsif ($age < 60*60*2) {
+ return "age0";
+ } elsif ($age < 60*60*24*2) {
+ return "age1";
+ } else {
+ return "age2";
+ }
+}
+
+# convert age in seconds to "nn units ago" string
+sub age_string {
+ my $age = shift;
+ my $age_str;
+
+ if ($age > 60*60*24*365*2) {
+ $age_str = (int $age/60/60/24/365);
+ $age_str .= " years ago";
+ } elsif ($age > 60*60*24*(365/12)*2) {
+ $age_str = int $age/60/60/24/(365/12);
+ $age_str .= " months ago";
+ } elsif ($age > 60*60*24*7*2) {
+ $age_str = int $age/60/60/24/7;
+ $age_str .= " weeks ago";
+ } elsif ($age > 60*60*24*2) {
+ $age_str = int $age/60/60/24;
+ $age_str .= " days ago";
+ } elsif ($age > 60*60*2) {
+ $age_str = int $age/60/60;
+ $age_str .= " hours ago";
+ } elsif ($age > 60*2) {
+ $age_str = int $age/60;
+ $age_str .= " min ago";
+ } elsif ($age > 2) {
+ $age_str = int $age;
+ $age_str .= " sec ago";
+ } else {
+ $age_str .= " right now";
+ }
+ return $age_str;
+}
+
+use constant {
+ S_IFINVALID => 0030000,
+ S_IFGITLINK => 0160000,
+};
+
+# submodule/subproject, a commit object reference
+sub S_ISGITLINK {
+ my $mode = shift;
+
+ return (($mode & S_IFMT) == S_IFGITLINK)
+}
+
+# convert file mode in octal to symbolic file mode string
+sub mode_str {
+ my $mode = oct shift;
+
+ if (S_ISGITLINK($mode)) {
+ return 'm---------';
+ } elsif (S_ISDIR($mode & S_IFMT)) {
+ return 'drwxr-xr-x';
+ } elsif (S_ISLNK($mode)) {
+ return 'lrwxrwxrwx';
+ } elsif (S_ISREG($mode)) {
+ # git cares only about the executable bit
+ if ($mode & S_IXUSR) {
+ return '-rwxr-xr-x';
+ } else {
+ return '-rw-r--r--';
+ };
+ } else {
+ return '----------';
+ }
+}
+
+# convert file mode in octal to file type string
+sub file_type {
+ my $mode = shift;
+
+ if ($mode !~ m/^[0-7]+$/) {
+ return $mode;
+ } else {
+ $mode = oct $mode;
+ }
+
+ if (S_ISGITLINK($mode)) {
+ return "submodule";
+ } elsif (S_ISDIR($mode & S_IFMT)) {
+ return "directory";
+ } elsif (S_ISLNK($mode)) {
+ return "symlink";
+ } elsif (S_ISREG($mode)) {
+ return "file";
+ } else {
+ return "unknown";
+ }
+}
+
+# convert file mode in octal to file type description string
+sub file_type_long {
+ my $mode = shift;
+
+ if ($mode !~ m/^[0-7]+$/) {
+ return $mode;
+ } else {
+ $mode = oct $mode;
+ }
+
+ if (S_ISGITLINK($mode)) {
+ return "submodule";
+ } elsif (S_ISDIR($mode & S_IFMT)) {
+ return "directory";
+ } elsif (S_ISLNK($mode)) {
+ return "symlink";
+ } elsif (S_ISREG($mode)) {
+ if ($mode & S_IXUSR) {
+ return "executable";
+ } else {
+ return "file";
+ };
+ } else {
+ return "unknown";
+ }
+}
+
+1;
--
1.7.1.454.ga8c50c
next prev parent reply other threads:[~2010-06-07 20:51 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-07 20:50 [RFC/PATCH 1/4] gitweb: Move subroutines to Gitweb::Config module Pavan Kumar Sunkara
2010-06-07 20:50 ` [RFC/PATCH 2/4] gitweb: Create Gitweb::HTML::Link module Pavan Kumar Sunkara
2010-06-07 20:50 ` [RFC/PATCH 3/4] gitweb: Create Gitweb::HTML module Pavan Kumar Sunkara
2010-06-07 20:50 ` Pavan Kumar Sunkara [this message]
2010-06-07 20:58 ` [RFC/PATCH 4/4] gitweb: Create Gitweb::HTML::String module Pavan Kumar Sunkara
2010-06-08 12:46 ` [RFC/PATCH 1/4] gitweb: Move subroutines to Gitweb::Config module Jakub Narebski
2010-06-08 13:50 ` Ævar Arnfjörð Bjarmason
2010-06-12 1:01 ` Jakub Narebski
2010-06-12 1:22 ` Ævar Arnfjörð Bjarmason
2010-06-12 1:41 ` Jakub Narebski
2010-06-08 14:13 ` Petr Baudis
2010-06-08 19:22 ` Pavan Kumar Sunkara
2010-06-08 19:55 ` Petr Baudis
2010-06-08 20:24 ` Pavan Kumar Sunkara
2010-06-08 20:50 ` Petr Baudis
2010-06-08 23:38 ` Jakub Narebski
2010-06-09 13:13 ` Jakub Narebski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1275943844-24991-4-git-send-email-pavan.sss1991@gmail.com \
--to=pavan.sss1991@gmail.com \
--cc=chriscool@tuxfamily.org \
--cc=git@vger.kernel.org \
--cc=jnareb@gmail.com \
--cc=pasky@ucw.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).