Skip to content

Class Tag

Ori Roth edited this page Apr 2, 2017 · 3 revisions

Synopsis of Class Tag

public class Tag { 
    /*
     * Forge (14)
     */
        Tag(String name, String[] flags); 
        Tag(Tag inner, String name, String[] flags); 
        final static Tag strong; 
        final static Tag em; 
        final static Tag pre; 
        final static Tag tt; 
        final static Tag p; 
        final static Tag u; 
        final static Tag h1; 
        final static Tag h2; 
        final static Tag h3; 
        final static Tag h4; 
        final static Tag h5; 
        final static Tag h6; 
    /*
     * Type (8)
     */
        String wrap(String s); 
        String wrapNL(String s); 
        Tag inside(String name, String[] flags); 
        String makeRegularExpression(); 
        Pattern makePattern(); 
        Matcher makeMatcher(String s); 
        final String begin; 
        final String end; 
    /*
     * Utilities (5)
     */
        static String replace(String text, String from, String to); 
        static String remove(String text, String tag); 
        static String beginTag(String name); 
        static String selfClosing(String name); 
        static String endTag(String name); 
    /*
     * Nested types (1)
     */
        static class TestMakePattern { ... } 
}

Output types: Matcher, Pattern.

Synopsis of Class Tag.TestMakePattern

public static class Tag.TestMakePattern { 
    /*
     * Forge (1)
     */
        TestMakePattern(); 
    /*
     * Type (8)
     */
        void testSimplePre(); 
        void testEmptyPre(); 
        void testCRLFinPre(); 
        void testLFinPre(); 
        void testSeveralLinesInPre(); 
        void testUpperCaseTag(); 
        void testMiXeDCaSeTag(); 
        void testDummyInContext(); 
} 

Code

// SSDLPedia
package il.ac.technion.cs.ssdl.strings;

import static il.ac.technion.cs.ssdl.strings.RE.anyNumberOfReluctant;
import static il.ac.technion.cs.ssdl.strings.RE.group;
import static il.ac.technion.cs.ssdl.strings.RE.ignoreCase;
import static il.ac.technion.cs.ssdl.utils.DBC.nonnull;
import static org.junit.Assert.assertEquals;
import il.ac.technion.cs.ssdl.stereotypes.Immutable;
import il.ac.technion.cs.ssdl.stereotypes.Instantiable;
import il.ac.technion.cs.ssdl.utils.Separate;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.junit.Test;

/**
 * A representation of an HTML tag, capable of wrapping a given String.
 * 
 * Author: Yossi Gil, the Technion.
 * See:  11/07/2008
 */
@Immutable @Instantiable public class Tag {
    /**
     * Wrap a given string within this tag.
     * 
     * s a non-null representing the string to wrap
     * Return: the string s wrapped with the tag, e.g., if
     *         s is "Hello" and the tag name is
     *         "b" then "Hello"" is returned.
     */
    public String wrap(final String s) {
        nonnull(s);
        return s.length() == 0 ? s : begin + s + end;
    }
    
    /**
     * Wrap a given string within newline characters and then within this tag.
     * 
     * s a non-null representing the string to wrap
     * Return: the string s wrapped with the tag, e.g., if
     *         s is "Hello" and the tag name is
     *         "b" then the string "\nHello\n"
     *         is returned.
     */
    public String wrapNL(final String s) {
        nonnull(s);
        return wrap("\n" + s + "\n");
    }
    
    /**
     * Instantiate a plain tag, i.e., a tag without any inner tags,
     * 
     * name the tag name, e.g., "font"
     * flags any number of HTML flags
     */
    public Tag(final String name, final String... flags) {
        nonnull(name);
        nonnull(flags);
        begin = beginTag(name + (flags.length == 0 ? "" : " " + Separate.by(flags, " ")));
        end = beginTag("/" + name);
    }
    
    /**
     * Instantiate a tag containing another tag
     * 
     * inner the inner tag; all instances of the newly created tag will
     *            be around this inner tag
     * name the tag name, e.g., "font"
     * flags any number of HTML flags
     */
    public Tag(final Tag inner, final String name, final String... flags) {
        nonnull(name);
        nonnull(flags);
        final Tag unnested = new Tag(name, flags);
        begin = unnested.begin + inner.begin;
        end = inner.end + unnested.end;
    }
    
    /**
     * A factory function, creating a new tag, containing this one. Typical use
     * demonstrates tag containment. The expression


       new Tag("strong").inside("tt")

     * returns a newly created nested Tag composed of a strong
     * within a tt tag.
     * 
     * name the name of the newly created tag, e.g., "font"
     * flags any number of HTML flags to be used with the newly created
     *            tag
     * Return: A newly created tag with the specified name and flags, containing
     *         this tag
     */
    public Tag inside(final String name, final String... flags) {
        return new Tag(this, name, flags);
    }
    
    /**
     * Make a regular expression to capture the opening and closing tag together
     * with the enclosed content.
     * 
     * Return: a regular expression to capture the tag and its content. The
     *         content is in group number 1.
     */
    public String makeRegularExpression() {
        return ignoreCase() + begin + group(anyNumberOfReluctant(".|[\r\n]")) + end;
    }
    
    /**
     * Make a Pattern to capture the opening and closing tag together
     * with the enclosed content.
     * 
     * Return: a regular expression to capture the tag and its content. The
     *         content is in group number 1.
     */
    public Pattern makePattern() {
        return Pattern.compile(makeRegularExpression());
    }
    
    /**
     * Make a Matcher of a given text, to capture the opening and
     * closing tag together with the enclosed content in this text.
     * 
     * s where to look for this text?
     * Return: Matcher of the parameter to capture the tag and its
     *         content. The content is in group number 1.
     */
    public Matcher makeMatcher(final String s) {
        return makePattern().matcher(s);
    }
    
    /**
     * The opening String of this tag.
     */
    public final String begin;
    /**
     * The closing String of this tag.
     */
    public final String end;
    /**
     * A pre-made instance, representing the HTML <strong> tag.
     */
    public final static Tag strong = new Tag("strong");
    /**
     * A pre-made instance, representing the HTML <em> tag.
     */
    public final static Tag em = new Tag("em");
    /**
     * A pre-made instance, representing the HTML <pre> tag.
     */
    public final static Tag pre = new Tag("pre");
    /**
     * A pre-made instance, representing the HTML <tt> tag.
     */
    public final static Tag tt = new Tag("tt");
    /**
     * A pre-made instance, representing the HTML <p> tag, used for
     * marking a paragraph.
     */
    public final static Tag p = new Tag("p");
    /**
     * A pre-made instance, representing the HTML <u> tag, used for
     * underlining the wrapped text.
     */
    public final static Tag u = new Tag("u");
    /**
     * A pre-made instance, representing the HTML <h1> tag.
     */
    public final static Tag h1 = new Tag("h1");
    /**
     * A pre-made instance, representing the HTML <h2> tag.
     */
    public final static Tag h2 = new Tag("h2");
    /**
     * A pre-made instance, representing the HTML <h3> tag.
     */
    public final static Tag h3 = new Tag("h3");
    /**
     * A pre-made instance, representing the HTML <h4> tag.
     */
    public final static Tag h4 = new Tag("h4");
    /**
     * A pre-made instance, representing the HTML <h5> tag.
     */
    public final static Tag h5 = new Tag("h5");
    /**
     * A pre-made instance, representing the HTML <h6> tag.
     */
    public final static Tag h6 = new Tag("h6");
    
    public static String replace(final String text, final String from, final String to) {
        return text//
                .replaceAll(ignoreCase() + beginTag(from), beginTag(to)) //
                .replaceAll(ignoreCase() + endTag(from), endTag(to));
    }
    
    public static String remove(final String text, final String tag) {
        return text//
                .replaceAll(ignoreCase() + beginTag(tag), "") //
                .replaceAll(ignoreCase() + endTag(tag), "") //
                .replaceAll(ignoreCase() + selfClosing(tag), "") //
        ;
    }
    
    /**
     * Make a String of an HTML opening tag with a given name.
     * 
     * name the name of the given tag.
     * Return: the name enclosed in angular brackets.
     */
    public static String beginTag(final String name) {
        return "<" + name + ">";
    }
    
    /**
     * Make a self closing String of an HTML tag with a given name.
     * 
     * name the name of the given tag.
     * Return: the name parameter, followed by slash (/) and enclosed in angular
     *         brackets.
     */
    public static String selfClosing(final String name) {
        return beginTag(name + " /");
    }
    
    /**
     * Make a String of an HTML closing tag with a given name.
     * 
     * name the name of the given tag.
     * Return: the name enclosed in angular brackets.
     */
    public static String endTag(final String name) {
        return beginTag("/" + name);
    }
    
    public static class TestMakePattern {
        private static final String tagRegularExpression = new Tag("dummy").makeRegularExpression();
        
        @Test public void testSimplePre() {
            assertEquals("ABC", "A<dummy>X</dummy>C".replaceFirst(tagRegularExpression, "B"));
        }
        
        @Test public void testEmptyPre() {
            assertEquals("ABC", "A<dummy></dummy>C".replaceFirst(tagRegularExpression, "B"));
        }
        
        @Test public void testCRLFinPre() {
            assertEquals("ABC", "A<dummy>\r\n</dummy>C".replaceFirst(tagRegularExpression, "B"));
        }
        
        @Test public void testLFinPre() {
            assertEquals("ABC", "A<dummy>\n</dummy>C".replaceFirst(tagRegularExpression, "B"));
        }
        
        @Test public void testSeveralLinesInPre() {
            assertEquals("ABC", "A<dummy>a\nb\r\nABCDE</dummy>C".replaceFirst(tagRegularExpression, "B"));
        }
        
        @Test public void testUpperCaseTag() {
            assertEquals("ABC", "A<DUMMY>a\nb\r\nABCDE</DUMMY>C".replaceFirst(tagRegularExpression, "B"));
        }
        
        @Test public void testMiXeDCaSeTag() {
            assertEquals("ABC", "A<DuMmY>a\nb\r\nABCDE</dUmMy>C".replaceFirst(tagRegularExpression, "B"));
        }
        
        @Test public void testDummyInContext() {
            assertEquals("" + //
                    "\t /**\r\n" + //
                    "\t  * BEFORE\r\n" + //
                    "\t  * Content\r\n" + //
                    "\t  * AFTER\r\n" + //
                    "\t  */" + //
                    "", ("" + //
                    "\t /**\r\n" + // 
                    "\t  * BEFORE\r\n" + //
                    "\t  * <dummy>\r\n" + //
                    "\t  * text\r\n" + //
                    "\t  * </dummy>\r\n" + //
                    "\t  * AFTER\r\n" + //
                    "\t  */" + //
                    "").replaceFirst(tagRegularExpression, "Content"));
        }
    }
}

Metrics

Metric Value Acronym Explanation
LOC 290 Lines Of Code Total number of lines in the code
SCC 57 SemiColons Count Total number of semicolon tokens found in the code.
NOT 997 Number Of Tokens Comments, whitespace and text which cannot be made into a token not included.
VCC 7118 Visible Characters Count The total number of non-white (i.e., not space, tab, newline, carriage return, form feed) characters.
CCC 3713 Code Characters Count Total number of non-white characters in tokens. White space characters in string and character literals are not counted.
UIC 79 Unique Identifiers Count The number of different identifiers found in the code
WHC 4 Weighted Horizontal Complexity A heuritistic on horizontal complexity

Statistics

Statistic Value
Average token length 3.7
Tokens/line 3.4
Visible characters/line 25
Code characters/line 13
Semicolons/tokens 5%
Comment text percentage 47%

Tokens by kind

Token Kind Occurrences
KEYWORD 145
OPERATOR 57
LITERAL 67
ID 313
PUNCTUATION 415
COMMENT 47
OTHER 525
Clone this wiki locally