DTE :]

Wednesday, July 6, 2016

Ekstraksi HTML dan Teks dengan Regex

Ekstraksi Umum

Memisahkan antara tag HTML dengan teks di sekitarnya:

var test = 'foo <a b="c">bar</a> baz <b> qux yo"s <c><d> wut?';
var results = test.match(/(<\/?[-:\w]+(?:\s[^<>]*?)?>)|([^<>]+)/g);

console.log(results);

Hasil:

[
    'foo ',
    '<a b="c">',
    'bar',
    '</a>',
    ' baz ',
    '<b>',
    ' qux yo"s ',
    '<c>',
    '<d>',
    ' wut?'
]

Dengan cara ini Anda dapat melakukan manipulasi teks dengan aman tanpa harus mempengaruhi tag HTML. Caranya adalah dengan mengecek terlebih dahulu apakah anggota merupakan tag HTML atau teks:

var output = "";
for (var i = 0, len = results.length; i < len; ++i) {
    var s = results[i];
    // Is this a HTML tag or text?
    if (s && s[0] === '<' && s.slice(-1) === '>') {
        // this is a HTML tag …
        output += s;
    } else {
        // do something with text …
        output += s.replace(/"/g, '&quot;');
    }
}

console.log(output);

Hasil:

'foo <a b="c">bar</a> baz <b> qux yo&quot;s <c><d> wut?'

Ekstraksi Spesifik

Kode di bawah ini akan memisahkan antara tag HTML dengan nama tertentu saja, sehingga teks bisa saja berisi tag HTML yang diperbolehkan. Ini berguna jika Anda ingin melakukan manipulasi teks di luar tag tertentu saja, misalnya tag <kbd>, <pre>, <script> dan <style>:

var test = 'foo <a b="c">bar</a> baz <b> qux yo"s <c><d> wut? <kbd>ignore this yo"s</kbd>';
var results = [];

test.replace(/(.*?)(<\/?(?:kbd|pre|script|style)(?:\s[^<>]*?)?>|$)/g, function(a, b, c) {
    b && results.push(b);
    c && results.push(c);
});

console.log(results);

Hasil:

[
    'foo <a b="c">bar</a> baz <b> qux yo"s <c><d> wut? ',
    '<kbd>',
    'ignore this yo"s',
    '</kbd>'
]

Berikut ini adalah cara mengubah karakter " yang berada di luar tag <kbd> menjadi &quot;:

var output = "";
var skip = false;
for (var i = 0, len = results.length; i < len; ++i) {
    var s = results[i];
    if (s && s[0] === '<' && s.slice(-1) === '>') {
        // check whether the HTML tag is an opening or closing tag …
        skip = s[1] && s[1] !== '/';
        output += s;
    } else {
        output += !skip ? s.replace(/"/g, '&quot;') : s; // replace or skip …
    }
}

console.log(output);

Hasil:

'foo <a b=&quot;c&quot;>bar</a> baz <b> qux yo&quot;s <c><d> wut? <kbd>ignore this yo"s</kbd>'

Versi PHP

PHP sudah memiliki fungsi khusus untuk menangani tugas ini:

$test = 'foo <a b="c">bar</a> baz <b> qux yo"s <c><d> wut?';
$results = preg_split('#(<\/?[-:\w]+(?:\s[^<>]*?)?>)#', $test, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);

var_dump($results);

Untuk melakukan ekstraksi tag HTML secara spesifik:

$results = preg_split('#(<\/?(?:kbd|pre|script|style)(?:\s[^<>]*?)?>)#', $test, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);

Labels: , , ,

Saturday, February 6, 2016

Parser Markdown Paling Sederhana

Dukungan Markup

Mendukung hampir semua markup seperti yang dinyatakan dalam dokumentasi Markdown Extra, kecuali markup catatan kaki, abbreviasi, daftar definisi, tautan ber–referensi dan gambar ber–referensi.

Labels: , ,

Saturday, March 1, 2014

Mengambil URL Gambar Pertama dari Posting

Versi PHP

function get_first_image_url($data, $default_url = null) {

    /**
     * Matched with ...
     * ----------------
     *
     * [1]. `![alt text](IMAGE URL)`
     * [2]. `![alt text](IMAGE URL "optional title")`
     *
     * ... and the single-quoted version of them
     *
     */
    if(preg_match_all('#\!\[.*?\]\(([^\s]+?)( +([\'"]).*?\3)?\)#', $data, $matches)) {
        return $matches[1][0];
    }

    /**
     * Matched with ...
     * ----------------
     *
     * [1]. `<img src="IMAGE URL">`
     * [2]. `<img foo="bar" src="IMAGE URL">`
     * [3]. `<img src="IMAGE URL" foo="bar">`
     * [4]. `<img src="IMAGE URL"/>`
     * [5]. `<img foo="bar" src="IMAGE URL"/>`
     * [6]. `<img src="IMAGE URL" foo="bar"/>`
     * [7]. `<img src="IMAGE URL" />`
     * [8]. `<img foo="bar" src="IMAGE URL" />`
     * [9]. `<img src="IMAGE URL" foo="bar" />`
     *
     * ... and the uppercased version of them, and the single-quoted version of them
     *
     */
    if(preg_match_all('#<img .*?src=([\'"])([^\'"]+?)\1.*? *\/?>#i', $data, $matches)) {
        return $matches[2][0];
    }

    return $default_url; // Default image URL if nothing matched
}

Penggunaan

<img src="<?php echo get_first_image_url($page['content'], 'img/no-image.png'); ?>">

$page['content'] cuma contoh. Anda harus mengambilnya dari konten posting Anda sesuai dengan API pada CMS yang Anda pakai.

Versi JavaScript

function getFirstImageURL(data, noImage) {

    /**
     * Matched with ...
     * ----------------
     *
     * [1]. `![alt text](IMAGE URL)`
     * [2]. `![alt text](IMAGE URL "optional title")`
     *
     * ... and the single-quoted version of them
     *
     */
    var matches = /\!\[.*?\]\(([^\s]+?)( +[\'"].*?[\'"])?\)/.exec(data);
    return matches ? matches[1] : noImage;

    /**
     * Matched with ...
     * ----------------
     *
     * [1]. `<img src="IMAGE URL">`
     * [2]. `<img foo="bar" src="IMAGE URL">`
     * [3]. `<img src="IMAGE URL" foo="bar">`
     * [4]. `<img src="IMAGE URL"/>`
     * [5]. `<img foo="bar" src="IMAGE URL"/>`
     * [6]. `<img src="IMAGE URL" foo="bar"/>`
     * [7]. `<img src="IMAGE URL" />`
     * [8]. `<img foo="bar" src="IMAGE URL" />`
     * [9]. `<img src="IMAGE URL" foo="bar" />`
     *
     * ... and the uppercased version of them, and the single-quoted version of them
     *
     */
    matches = /<img .*?src=[\'"]([^\'"]+?)[\'"].*? *\/?>/i.exec(data);
    return matches ? matches[1] : noImage;

}

Penggunaan

var img = '<img src="' + getFirstImageURL(sourceText, 'img/no-image.png') + '">';
document.write(img);

sourceText cuma contoh. Anda harus mengambilnya dari konten posting Anda, misalnya dengan cara ini:

var sourceText = document.querySelector('.post-body').innerHTML;

Labels: , , , ,

Friday, February 14, 2014

Regex untuk Validasi Tag HTML

<("[^"]*"|'[^']*'|[^'">])*>

Cocok untuk pola ini:

  1. <input value='>'>
  2. <input value='<'>
  3. <a href="//www.nama_web.com">
  4. <br>, <br/>
  5. <input value="'" id="test">, <input value='"' id='test'>

Referensi: How to Validate HTML Tag with Regular Expression

Labels: , , ,

Wednesday, December 19, 2012

Konversi Angka Menjadi Format Mata Uang

Fungsi ini digunakan untuk mengubah deret angka menjadi pola mata uang dimana setiap tiga deret angka akan ditambahi sebuah titik atau koma setelahnya/sebelumnya, dimulai dari belakang:

function addCommas(nStr) {
    nStr += '';
    x = nStr.split('.');
    x1 = x[0];
    x2 = x.length > 1 ? '.' + x[1] : '';
    var rgx = /(\d+)(\d{3})/;
    while (rgx.test(x1)) {
        x1 = x1.replace(rgx, '$1' + ',' + '$2');
    }
    return x1 + x2;
}

Penggunaan

addCommas('10000000'); // Hasil => 10,000,000

Demo


Sumber: Formatting Numbers in JavaScript - Add Commas

Labels: , ,

Friday, September 7, 2012

Mendapatkan Nama File dari URL

function getTitle(str) {
    var a = str.lastIndexOf('/') + 1,
        b = str.lastIndexOf('.');
    str = decodeURIComponent(str.substring(a, b));
    str = str.replace(/[\+\-\_]/g, " ");
    return str;
}

Penggunaan

var result = getTitle("//www.blablablah.com/files/JavaScript+Images.jpg");
// Hasil => "JavaScript Images"

Lihat Demo

URL bisa diambil dari mana saja. Sebagai contoh, di sini Saya mencoba mengambil URL dari sebuah gambar untuk disaring sebagai judul:

var a = document.getElementsByTagName('img')[0].src;
document.getElementById('title-container').innerHTML = getTitle(a);

Lihat Demo

Labels: , ,

Wednesday, September 5, 2012

Syntax Highlighter dengan PRISM

Syntax Highlighter dengan PRISM

Meskipun di blog ini Saya menggunakan syntax highlighter dari Software Maniacs, tapi jika diminta untuk memilih dari segi kecepatannya, maka Saya akan menggunakan PRISM, sebuah syntax highlighter untuk HTML, CSS, Java dan JavaScript (bekerja juga untuk PHP dengan asumsi sebagai markup):

Lihat Demo

Proses instalasi hanya membutuhkan dua langkah. Pertama-tama masuklah ke halaman editor HTML Template Anda kemudian pilih Edit HTML dan klik Lanjutkan. Temukan kode ini:

]]></b:skin>

Salin kode CSS ini dan letakkan di atasnya:

/*
Tema pribadi => RDark
Saya buat berdasarkan tema-tema SyntaxHighligter dari Alex Gorbatchev
URL: http://alexgorbatchev.com/SyntaxHighlighter/manual/themes/rdark.html*/

pre {
  padding:.5em 1em;
  margin:.5em 0;
  white-space:pre;
  word-wrap:normal;
  overflow:auto;
  background-color:#1B2426;
}

code {
  font-family:Consolas,Monaco,'Andale Mono','Courier New',Courier,Monospace;
  line-height:16px;
  color:#B43D3D;
  background-color:#eee;
  border:1px solid #ddd;
  padding:1px 2px;
}

pre code {
  display:block;
  background:none;
  border:none;
  color:#B9BDB6;
  direction:ltr;
  text-align:left;
  word-spacing:normal;
  padding:0 0;
}

code .token.punctuation {
  color:#83405A;
}

pre code .token.punctuation {
  color:#B9BDB6;
}

code .token.comment,
code .token.prolog,
code .token.doctype,
code .token.cdata {
  color:#435A4D;
}

code .namespace {
  opacity:.8;
}

code .token.property,
code .token.tag,
code .token.boolean,
code .token.number {
  color:#5BA1CF;
}

code .token.selector,
code .token.attr-name,
code .token.string {
  color:#986A7C;
}

pre code .token.selector,
pre code .token.attr-name,
pre code .token.string {
  color:#E0E8FF;
}

code .token.entity,
code .token.url,
pre .language-css .token.string,
pre .style .token.string {
  color:#E0E8FF;
}

code .token.operator {
  color:#878A85;
}

code .token.atrule,
code .token.attr-value {
  color:#48D30F;
}

pre code .token.atrule,
pre code .token.attr-value {
  color:#48E638;
}

code .token.keyword {
  color:#47A1CF;
  font-style:italic;
}

code .token.comment {
  font-style:italic;
}

code .token.regex {
  color:#B43D3D;
}

code .token.important {
  font-weight:bold;
}

code .token.entity {
  cursor:help;
}

Setelah itu temukan kode ini:

</body>

Letakkan skrip ini di atasnya:

<script "//cdn.rawgit.com/tovic/dte-project/2fd2d2971c3398029ea5e149696447243e7f4d94/prism.min.js"></script>

Klik Simpan Template.

Cara Pemakaian

Setiap tipe bahasa memiliki kelasnya masing-masing:

  • HTML, XML, PHPlanguage-markup
  • CSSlanguage-css
  • JavaScriptlanguage-javascript
  • Javalanguage-java

Kode yang ingin diberi efek harus berada di dalam tag pre > code seperti ini:

<pre><code class="language-markup"> ... kode HTML (yang sudah di`escape`) di sini ... </code></pre>
<pre><code class="language-css"> ... kode CSS di sini ... </code></pre>
<pre><code class="language-javascript"> ... kode JavaScript di sini ... </code></pre>
<pre><code class="language-java"> ... kode Java di sini ... </code></pre>

Tema-tema yang asli bisa Anda temukan di situs sumbernya, PRISM. Atau mungkin Anda mau membuatnya sendiri?

Labels: , , , ,

Saturday, July 21, 2012

Beberapa Pola Regex Bermanfaat

// email:
    /^([^0-9\.\+])([\w.\+])+\@(([\w\-])+\.)+[a-zA-Z0-9]{2,}/
// url:
    /^(http:\/\/)([\w]+\.){1,}[A-Z]{2,}\b/gi
// creditcard:
    /^[0-9]{16}$/gi
// ccspecial:
    /^[0-9]{12}$/gi
// cvv:
    /^[0-9]{3,4}$/gi
// phone:
    /^[0-9]{10}$/gi
// postcode:
    /^[0-9]{4}$/gi
// numeric:
    /^[0-9]+$/gi
// alphanumeric:
    /^[0-9a-f\-\s]+$/gi
// dob:
    /^([0-9]{1,2}[\/]){2}[0-9]{4}$/g
// macAddress:
    /^([0-9a-fA-F]{2}[:-]){5}[0-9a-fA-F]{2}$/gi
// username:
    /^[a-z0-9\-_\.]{6,12}$/gi
// names:
    /^[a-z\.\-\s\']{1,}$/gi
// nonalpha:
    /[^A-Za-z]+/g
// nonalphanumeric:
    /[^A-Za-z0-9]+/g
// nonnumeric:
    /[^0-9\-\.]/g
// nonnumericExplicit:
    /[^0-9]/g

Sumber: Snipt – Some JS Regexes

Labels: , ,

Sunday, July 15, 2012

Memperbesar/Mengubah Ukuran Thumbnail Posting

Memperbesar Thumbnail Posting

Pertanyaan Al-Firouz: Tentang bagaimana cara memperbesar thumbnail pada posting auto read-more tanpa JavaScript dengan jQuery:

Pertanyaan Al-Firouz: Tentang bagaimana cara memperbesar thumbnail
Dalam pesan Facebook

Pertama-tama, Saya tidak akan memberikan metode mengubah ukuran thumbnail Picasa dengan jQuery terlebih dahulu karena ada cara sederhana yang bisa dilakukan dengan mudah menggunakan JavaScript mentah. Pada intinya, kita hanya mencoba mengubah ukuran thumbnail kecil dari path-nya seperti yang pernah Saya ulas dengan cukup jelas di artikel Optimasi Thumbnail pada Posting Auto Read-More dan Widget Blogger, yaitu dengan cara mengubah ukuran standar thumbnail 72 × 72 piksel s72-c menjadi ukuran yang lain, misalnya s200-c.

Metode 1: Menggunakan JavaScript Murni

Salin kode ini dan letakkan di atas tag </body>:

<b:if cond='data:blog.pageType != &quot;static_page&quot;'>
<b:if cond='data:blog.pageType != &quot;item&quot;'>
<script>
//<![CDATA[
function resizeThumb(parentID, size) {
    var parent = document.getElementById(parentID),
        image = parent.getElementsByTagName('img');
    for (var i = 0; i < image.length; i++) {
        image[i].src = image[i].src.replace(/\/s72\-c/, "/s" + size + "-c");
        image[i].width = size;
        image[i].height = size;
    }
}
resizeThumb('main-wrapper', 200);
//]]>
</script>
</b:if>
</b:if>

Fungsi dieksekusi pada bagian ini:

resizeThumb('main-wrapper', 200);

main-wrapper adalah ID kolom posting, dan 200 adalah ukuran thumbnail baru. Kode di atas akan mengubah ukuran thumbnail dari 72 × 72 piksel menjadi 200 × 200 piksel.

Ganti juga ukuran width dan height thumbnail posting dalam kode CSS ini:

.post-thumbnail {
  width:72px;
  height:72px;
  float:left;
  margin:0 10px 0 0;
}

… menjadi berukuran sama dengan ukuran pembesaran thumbnail. Menyesuaikan contoh di atas, maka ukuran lebar dan tinggi thumbnail harus diubah menjadi 200px.

Simpan semua perubahan dan lihat hasilnya.

Lihat Sampel

Metode 2: Menggunakan jQuery

Pada intinya cara kerjanya sama, hanya metodenya saja yang berbeda. Salin kode ini dan letakkan di atas kode </head> atau </body>:

<b:if cond='data:blog.pageType != &quot;static_page&quot;'>
<b:if cond='data:blog.pageType != &quot;item&quot;'>
<script>
//<![CDATA[
function resizeThumb(el, from, to) {
    $(el).each(function() {
        $(this).attr({
            'src': $(this).attr('src').replace('/s'+from+'-c/', '/s'+to+'-c/'),
            'width': to, 'height': to
        });
    });
}
$(function() {
    resizeThumb('.post-thumbnail', '72', '200'); // Ubah ukuran thumbnail dari 72 menjadi 200
});
//]]>
</script>
</b:if>
</b:if>

Di sini Saya menggunakan selektor $('.post-thumbnail') untuk menargetkan thumbnail posting secara langsung. Anda bisa saja mengubah selektornya menjadi $('#main-wrapper img') atau $('.post img:first') atau bahkan yang lainnya jika template Anda memiliki struktur elemen yang unik. Pada intinya, targetkan gambarnya! Alasan Saya tidak menggunakan nama kelas thumbnail pada versi manipulasi JavaScript adalah karena Saya tidak ingin mengambil resiko mengingat document.getElementsByClassName tidak didukung oleh beberapa peramban tua - When can I use getElementsByClassName?

Lihat Sampel

Thumbnail Lain?

Bukan hanya thumbnail pada posting saja yang bisa diubah ukurannya, tapi juga thumbnail-thumbnail pada widget lain, misalnya pada widget Posting Populer yang caranya juga pernah dituliskan oleh MS-Potilas di artikelnya (Kebetulan Saya mendapatkan ide JavaScript mentahnya dari sana). Di sini Saya hanya mengonversi kodenya menjadi plugin. Asalkan thumbnail tersebut diunggah pada direktori Picasa, maka kita bisa menemukan ciri khususnya dalam path lokasi gambar seperti s72-c, s200, s1600 dan lain sebagainya. Dari kunci itulah kita bisa mengubah ukuran-ukuran gambar menggunakan JavaScript dengan cara mengganti besarannya. berikut ini adalah contoh sederhana bagaimana cara memperbesar thumbnail pada widget Posting Populer:

Versi JavaScript

<script>
//<![CDATA[
function resizeThumb(parentID, size) {
    var parent = document.getElementById(parentID),
        image = parent.getElementsByTagName('img');
    for (var i = 0; i < image.length; i++) {
        image[i].src = image[i].src.replace(/\/s72\-c/, "/s" + size + "-c");
        image[i].width = size;
        image[i].height = size;
    }
}
// Mengubah ukuran thumbnail widget Posting Populer
resizeThumb('PopularPosts1', 200);
//]]>
</script>

Versi jQuery

<script>
//<![CDATA[
function resizeThumb(el, from, to) {
    $(el).each(function() {
        $(this).attr({
            'src': $(this).attr('src').replace('/s'+from+'-c/', '/s'+to+'-c/'),
            'width': to, 'height': to
        });
    });
}
// Mengubah ukuran thumbnail widget Posting Populer
$(function() {
    resizeThumb('#PopularPosts1 img', '72', '200');
});
//]]>
</script>

bisa dilepaskan jika tujuan kita adalah untuk mengubah ukuran thumbnail widget, karena umumnya widget muncul pada semua tipe halaman.

Catatan Tambahan: Saya melihat beberapa pembaca yang mendeklarasikan fungsi resizeThumb() berkali-kali pada tempat yang berbeda. Padahal fungsi ini cukup dinyatakan satu kali saja (Saya sarankan untuk meletakkannya di area <head>):

function resizeThumb(parentID, size) { ... }

Setelah itu Anda bisa menggunakan fungsi tersebut sebanyak yang Anda mau pada elemen mana saja:

resizeThumb('Blog1', 300);
resizeThumb('PopularPosts1', 200);
resizeThumb('Widget1', 50);
...

Labels: , , , , ,

Thursday, July 12, 2012

No Live Links · Mencegah Tautan Aktif Masuk ke dalam Komentar

function blockLinks(parentID, children) {
    var parent = document.getElementById(parentID), content;
    if (!parent) return;
    content = parent.getElementsByTagName(children);
    for (var i = 0, len = content.length; i < len; ++i) {
        if (content[i].innerHTML.indexOf('</a>') !== -1) {
            content[i].innerHTML = '<mark>No live link!!!</mark> Dilarang nyepam di sini!';
            content[i].className += ' spammer-detected';
        }
    }
}
// Jalankan fungsi!
// Seleksi elemen induk dengan id='comment-holder' ...
// dan periksa semua konten paragraf di dalamnya!
blockLinks('comment-holder', 'p');

Fungsi sederhana untuk mencegah hadirnya tautan aktif dalam daftar komentar. Cara kerjanya, JavaScript akan menyeleksi sebuah elemen induk dengan ID tertentu (dalam hal ini: #comment-holder), kemudian akan melihat semua item di dalamnya (dalam hal ini <p>). Jika setidaknya sebuah tautan ditemukan, dengan sekejap ganti semua konten item tersebut dengan pesan larangan tertentu.

Demo

Lihat Demo

Labels: , , , ,

Wednesday, June 13, 2012

Eksperimen Syntax Highlighter

Syntax Highlighter

HAAAAAHHHHHHHHH!!!! Mulai iseng lagi…

jQuery

// Pure jQuery Syntax Highlighter by Taufik Nurrohman
// Still an experimental :)
// https://plus.google.com/108949996304093815163/about

$(function() {
    $('pre').each(function() {
        var list = "(true|false|null|main|in|endif|if|endfor|for|while|finally|var|new|function|do|return|void|else|break|catch|instanceof|with|throw|case|default|try|this|switch|continue|typeof|delete)",
            rep1 = new RegExp(list + " ", "ig"),
            rep2 = new RegExp(list + "( ?)<span", "ig"),
            $this = $(this);
        $this.html($this.html()
        .replace(/(<br>|\n)$/ig, "")
        .replace(/(\t)/g, "    ")
        .replace(/&quot;/ig, "\"")
        .replace(/&#39;|&apos;/ig, "\'")
        .replace(/(.?)'(.*?)'/g, "$1<span class='str'>\'$2\'</span>")
        .replace(/(.?)"(.*?)"/g, "$1<span class='str'>\"$2\"</span>")
        .replace(/(.?)(""|'')/g, "$1<span class='value'>$2</span>")
        .replace(/(#[A-F0-9]{3,6})/ig, "<span class='hex'>$1</span>")
        .replace(/(\d+(?!(.*&lt;)))/g, "<span class='num'>$1</span>")
        .replace(/((#|\.)[\-_A-Z0-9]+)/ig, "<span class='selector'>$1</span>")
        .replace(/(\{|\}|\(|\)|\[|\])/g, "<span class='bracket'>$1</span>")
        .replace(/&lt;(.*?)&gt;/g, "<span class='tag'>&lt;$1&gt;</span>")
        .replace(/&lt;!--([\s\S]*?)--&gt;/gm, "<span class='comment'>&lt;!--$1--&gt;</span>")
        .replace(/\/\*([\s\S]*?)\*\//gm, "<span class='comment'>/*$1*/</span>")
        .replace(/[^\:]\/\/(.*)/g, "<span class='comment'>//$1</span>")
        .replace(/<\/span>\/(.*)\/([gim]+),( ?)<span class='str'>/g, "</span><span class='regexp'>/$1/$2</span>, <span class='str'>")
        .replace(rep1, "<span class='keyword'>$1</span> ")
        .replace(rep2, "<span class='keyword'>$1</span>$2<span")
        .replace(/function<\/span> (.[^<]*)<span/g, "function</span> <span class='name'>$1</span><span")
        .replace(/([\-_A-Z]+)(?=(\s+|)):(.(?!\{)*)/ig, "<span class='attribute'>$1</span>:$2$3")
        .replace(/h<span class='num'>([1-6])<\/span>/ig, "h$1")
        .replace(/!important/ig, "<mark class='important'>!important</mark>")
        .replace(/&lt;!(doctype)(.*)&gt;/ig, "<span class='doctype'>&lt;!$1$2&gt;</span>")
        .replace(/@<span class='attribute'>(import|page|media|charset|keyframes|font-face)<\/span>/ig, "@$1")
        .replace(/(@(import|page|media|charset|keyframes|font-face))/ig, "<span class='keyword'>$1</span>")
        .replace(/<span class='bracket'>\[<\/span>(.*)<span class='bracket'>\]<\/span>/ig, "<span class='array'>[$1]</span>")
        ).find('.str span, .regexp span, .comment span, .doctype span, .hex span, .array span, .url span').contents().unwrap();
        $this.append('<div class="the-num"></div>');

        // Insert the line number
        var num = $this.html().split(/\n|<br>/).length,
            count = 0;
        for (var i = 0; i < num; i++) {
            count = count + 1;
            $this.find('.the-num').append(count + '.<br/>');
        }
        $this.css('padding-left', $this.find('.the-num').outerWidth()+14);

    });
});

CSS

pre {
  background-color:white;
  color:#069;
  padding:0em 1em;
  overflow:auto;
  white-space:pre;
  word-wrap:normal;
  font:bold 12px/1.5em "Consolas","Bitstream Vera Sans Mono","Courier New",Courier,monospace !important;
  position:relative;
  margin:0 0 1em;
}

pre .the-num {
  position:absolute;
  top:0;
  bottom:0;
  left:0;
  padding:0 1em;
  color:#999;
  background-color:#eee;
  border-right:2px solid #ccc;
}

pre .bracket   {color:darkblue;}
pre .tag,
pre .tag .keyword,
pre .tag .attribute {color:blue;}
pre .selector  {color:blue;}
pre .attribute,
pre .regexp    {color:darkorange;}
pre .str       {color:green;}
pre .tag .str  {color:brown;}
pre .keyword   {color:darkred;}
pre .comment   {font-style:italic;color:#999;}
pre .num,
pre .hex       {color:darkviolet;}
pre .name,
pre .important,
pre .array     {color:red;}
pre .important {background-color:yellow;}
pre .doctype   {color:magenta;}

Lihat Demo


Lainnya

Labels: , , , ,

Tuesday, May 22, 2012

Paket JavaScript Fitur Manipulasi Komentar Blogger

Manipulasi komentar Blogger
Manipulasi komentar Blogger

Rilis paket JavaScript manipulasi komentar Blogger! Setelah beberapa kali menemukan masalah pada kode JavaScript manipulasi komentar yang biasa digunakan (Saya rasa ada banyak dimana-mana dalam berbagai versi), kali ini Saya akan memperkenalkan versi yang lebih aman dan lebih lengkap. Berikut ini adalah beberapa fitur yang ada:

  • Menyisipkan gambar pada komentar Blogger.
  • Menyisipkan video YouTube ke dalam komentar Blogger.
  • Menyisipkan tag <code>
  • Menyisipkan tag <pre>
  • Menyisipkan <blockquote>
  • Mengubah teks emotikon secara otomatis.
  • Dua metode penyisipan kode untuk manipulasi komentar Blogger.
  • Aman. Kode braket kotak yang keliru saat diimplementasikan tidak akan diparse menjadi tag HTML.
  • CSS Fallback. Artinya bahwa jika JavaScript tidak bekerja, beberapa elemen penting masih bisa bekerja sebagaimana saat menggunakan JavaScript (Progressive Enhancement).
  • Pengaturan ukuran dan posisi dilakukan melalui CSS.

Lihat Sampel Manipulasi

Ada beberapa hal yang menjadi perhatian Saya di sini:

Perhatian Pertama: Rusaknya DOM (?)

Rusaknya elemen-elemen HTML karena terkadang JavaScript memanipulasi karakter dengan perintah yang salah yang berasal dari faktor manusia. Hal ini biasanya terjadi ketika penulis melakukan kesalahan saat menerapkan kode. Salah satu contoh umum adalah saat menyisipkan gambar dengan manipulasi braket kotak seperti ini:

[img]gambar-pemandangan.jpg[/img]

Kode di atas adalah kode yang dituliskan secara benar, sehingga kita bisa membuat manipulasi dengan regex untuk mengubahnya menjadi tag <img> seperti ini:

var a = something.innerHTML;
    a = a.replace(/\[img\]/ig, "<img src='");
    a = a.replace(/\[\/img\]/ig, "' alt='' />");
another.innerHTML = a;

Sehingga JavaScript akan mengubah kode di atas menjadi seperti ini:

<img src='gambar-pemandangan.jpg' alt='' />

Tapi terkadang kita juga bisa saja mengalami kesalahan ketik seperti ini:

[img]gambar-pemandangan.jpg[img]

Hal ini sangat berbahaya, karena sekali saja Anda melakukan kesalahan terhadap peraturan JavaScript yang Anda buat sendiri, meskipun hanya satu kode tapi itu bisa merusak dokumen HTML secara global!

<img src='gambar-pemandangan.jpg<img src='

Masalah system of blog pada diskusi hilangnya beberapa item komentar karena JavaScript - Permalink

Oleh karena itu, dibandingkan mengubah setiap karakter unik secara terpisah, akan lebih baik jika Anda menggabungkannya dalam satu kelompok, antara braket pembuka dan braket penutup:

var a = something.innerHTML;
    a = a.replace(/\[img\](.[^\]]*)\[\/img\]/ig, "<img src='$1' alt='' />");
another.innerHTML = a;

Cara di atas jauh lebih aman, karena JavaScript hanya akan memanipulasi karakter [img] yang memiliki penutupnya yaitu [/img]. Jika karakter akhirnya bukan [/img], maka JavaScript akan mengabaikannya. Itu adalah konsep yang Saya pegang di sini.

Penggunaan Tag HTML Asli

Ini penting, dan Saya memang lebih memfokuskan karya ini pada penerapan tag HTML murni, bukan braket kotak atau karakter-karakter paksaan lainnya. Blogger sudah memiliki fasilitas pengecekan validasi tag HTML pada formulir komentar mereka. Singkatnya, tag HTML bisa menjadi sesuatu yang sangat aman karena Blogger secara normal akan memastikan bahwa kode yang Anda tuliskan benar:

var a = something.innerHTML;
    // Mengubah tag <i> menjadi <code>
    a = a.replace(/<i rel="code">(.[^>]*)<\/i>/g, "<code>$1<\/code>");
another.innerHTML = a;

Progressive Enhancement

Saya menggunakan dua tag HTML utama yaitu <i> dan <b> dengan atribut rel yang berbeda-beda. Apa yang Saya lakukan di sini adalah Saya akan memastikan bahwa jika JavaScript tidak bekerja, maka tampilan tag HTML manipulator akan tetap sama dengan tag HTML yang akan menjadi penggantinya. Sebagai contoh, Saya akan menyamakan tampilan tag <pre> dengan <i rel="pre"> sebagai cadangan:

pre,
i[rel="pre"] {
  display:block;
  font:normal normal 12px/normal Monaco,"Courier New",Courier,Monospace;
  word-wrap:normal;
  white-space:pre;
  background-color:black;
  color:white;
  padding:.5em 1em;
  overflow:auto;
}

Dengan begitu Saya bisa memastikan bahwa jika tag <i rel="pre"> berhasil dimanipulasi menjadi tag <pre>, maka tampilan pada peramban akan tampak seperti apa adanya tag <pre>. Namun jika gagal dimanipulasi, tampilan tag <i rel="pre"> akan tetap tampak sebagai sesuatu yang memiliki wujud sama dengan tag <pre> - Selengkapnya bisa dibaca di CSS Fallback untuk Manipulasi Bagian Komentar

Mengatur Tampilan Melalui CSS

Semua pengaturan seperti lebar elemen, posisi dan warna dilakukan melalui CSS.


Cara Memasang Fitur Ini

Pertama-tama masuklah ke halaman editor HTML blog Anda. Klik Edit HTML dan klik Lanjutkan:

Edit HTML Blogger
Mengedit HTML

Temukan kode ini:

</head>

Salin kode CSS ini dan letakkan di atasnya:

<b:if cond='data:blog.pageType == &quot;item&quot;'>
<style>
/* Add More Features to the Blogger Comments by Taufik Nurrohman @http://www.dte.web.id */
img.emo {
  display:inline-block;
  vertical-align:middle;
}

#comment-holder .cm-youtube {
  display:block;
  border:none;
  background-color:#333;
  width:370px;
  height:218px;
  margin:0 auto 30px;
}

#comment-holder .cm-image {
  display:block;
  margin:0 auto 15px;
  outline:none;
  border:1px solid #ccc;
  background-color:white;
  -webkit-box-shadow:0 1px 3px rgba(0,0,0,.2);
  -moz-box-shadow:0 1px 3px rgba(0,0,0,.2);
  box-shadow:0 1px 3px rgba(0,0,0,.2);
  padding:5px;
  max-width:96%;
  height:auto;
  width:auto\9;
}

#comment-holder code,
#comment-holder i[rel="code"],
#comment-holder pre,
#comment-holder i[rel="pre"] {
  font:normal normal 12px/normal Monaco,"Courier New",Courier,Monospace;
  color:blue;
}

#comment-holder pre,
#comment-holder i[rel="pre"] {
  display:block;
  background-color:#333;
  color:white;
  padding:.5em 1em;
  word-wrap:normal;
  white-space:pre;
  overflow:auto;
}

#comment-holder blockquote,
#comment-holder b[rel="quote"] {
  margin:0 2%;
  background-color:#eee;
  padding:1em 1.2em;
  border-left:4px solid #7498AD;
  display:block;
  font-weight:bold;
  font-style:italic;
}

#comment-holder i[rel="image"],
#comment-holder i[rel="youtube"] {
  display:block;
  overflow:hidden;
  border:2px solid black;
  position:relative;
  width:170px;
  height:100px;
  margin:0 auto 30px;
}

#comment-holder i[rel="image"]:before,
#comment-holder i[rel="youtube"]:before {
  content:"Please enable your JavaScript to see this image!";
  position:absolute;
  top:0;
  right:0;
  bottom:0;
  left:0;
  background-color:red;
  color:white;
  font-weight:bold;
  text-align:center;
  padding:15px 0;
}

#comment-holder i[rel="youtube"]:before {content:"Please enable your JavaScript to watch this video!"}
</style>
</b:if>

Setelah itu temukan kode ini:

</body>

Salin kode ini dan letakkan di atasnya:

<b:if cond='data:blog.pageType == &quot;item&quot;'>
<script>
//<![CDATA[
// Add More Features to the Blogger Comments
// Fix some bugs that I got from some similar code out here :)
// Date: 21 May 2012
// Time: 22:50 WIB
// Author: Taufik Nurrohman
// URL: https://plus.google.com/108949996304093815163/about
function repText(id) {
    var a = document.getElementById(id);
    if (!a) return;
    var b = a.innerHTML, c = "//cdn.rawgit.com/tovic/dte-project/0ef9de902cf286a77272f9b3c6f8168c17ab61c6/emoticon/";
    // Images
    b = b.replace(/<i rel="image">(.*?)<\/i>/ig, "<img class='cm-image' src='$1' alt='loading...' \/>");
    b = b.replace(/\[img\](.*?)\[\/img\]/ig, "<img class='cm-image' src='$1' alt='loading...' \/>");
    // YouTube video
    b = b.replace(/<i rel="youtube">https?:\/\/www\.youtube\.com\/embed\/(.*?)<\/i>/ig, "<iframe class='cm-youtube' src='https://www.youtube.com/embed/$1'><\/iframe>");
    b = b.replace(/<i rel="youtube">(https?:\/\/youtu\.be\/|https?:\/\/www\.youtube\.com\/watch\?v\=)(.*?)<\/i>/ig, "<iframe class='cm-youtube' src='https://www.youtube.com/embed/$2'><\/iframe>");
    b = b.replace(/\[youtube\]https?:\/\/www\.youtube\.com\/embed\/(.*?)\[\/youtube\]/ig, "<iframe class='cm-youtube' src='https://www.youtube.com/embed/$1'><\/iframe>");
    b = b.replace(/\[youtube\](https?:\/\/youtu\.be\/|https?:\/\/www\.youtube\.com\/watch\?v\=)(.*?)\[\/youtube\]/ig, "<iframe class='cm-youtube' src='https://www.youtube.com/embed/$2'><\/iframe>");
    // Code & text block
    b = b.replace(/<i rel="code">(.*?)<\/i>/ig, "<code>$1<\/code>");
    b = b.replace(/<i rel="pre">(.*?)<\/i>/ig, "<pre>$1<\/pre>");
    b = b.replace(/<b rel="quote">(.*?)<\/b>/ig, "<blockquote>$1<\/blockquote>");
    b = b.replace(/\[code\](.*?)\[\/code\]/ig, "<code>$1<\/code>");
    b = b.replace(/\[pre\](.*?)\[\/pre\]/ig, "<pre>$1<\/pre>");
    b = b.replace(/\[blockquote\](.*?)\[\/blockquote\]/ig, "<blockquote>$1<\/blockquote>");
    // Finishing YouTube and Reduce filesize from images that uploaded by Blogger
    b = b.replace(/&feature=[\w-]*/ig, "");
    b = b.replace(/\/s(640|1600)/g, "/s400");
    // Emoticons
    b = b.replace(/\s:\)+/g, " <img class='emo' alt=':)' src='" + c + "01.gif'\/>");
    b = b.replace(/\s;\)+/g, " <img class='emo' alt=';)' src='" + c + "02.gif'\/>");
    b = b.replace(/\s:\(/g, " <img class='emo' alt=':(' src='" + c + "03.gif'\/>");
    b = b.replace(/\s=\(/g, " <img class='emo' alt='=(' src='" + c + "04.gif'\/>");
    b = b.replace(/\s@@,/g, " <img class='emo' alt='@@,' src='" + c + "05.gif'\/>");
    b = b.replace(/\s:s/ig, " <img class='emo' alt=':s' src='" + c + "07.gif'\/>");
    b = b.replace(/\s:(\\|\/)/g, " <img class='emo' alt=':\\' src='" + c + "08.gif'\/>");
    b = b.replace(/\s:D/g, " <img class='emo' alt=':D' src='" + c + "09.gif'\/>");
    b = b.replace(/\s=D/g, " <img class='emo' alt='=D' src='" + c + "10.gif'\/>");
    b = b.replace(/\s\^:D/g, " <img class='emo' alt='^:D' src='" + c + "11.gif'\/>");
    b = b.replace(/\s\^_?\^/g, " <img class='emo' alt='^_^' src='" + c + "12.gif'\/>");
    b = b.replace(/\s:'\(/g, " <img class='emo' alt=':&#39;(' src='" + c + "13.gif'\/>");
    b = b.replace(/\sT_T/ig, " <img class='emo' alt='T_T' src='" + c + "15.gif'\/>");
    b = b.replace(/\sB\)/g, " <img class='emo' alt='B)' src='" + c + "16.gif'\/>");
    b = b.replace(/\s:Q/ig, " <img class='emo' alt=':Q' src='" + c + "17.gif'\/>");
    b = b.replace(/\s7:\(/g, " <img class='emo' alt='7:(' src='" + c + "19.gif'\/>");
    b = b.replace(/\s:p/ig, " <img class='emo' alt=':p' src='" + c + "20.gif'\/>");
    b = b.replace(/\s:Oz+/ig, " <img class='emo' alt=':Ozzz' src='" + c + "21.gif'\/>");
    b = b.replace(/\s7:O/ig, " <img class='emo' alt='7:O' src='" + c + "22.gif'\/>");
    b = b.replace(/\s\\o\//ig, " <img class='emo' alt='\\o/' src='" + c + "23.gif'\/>");
    b = b.replace(/\s\\m\//ig, " <img class='emo' alt='\\m/' src='" + c + "24.gif'\/>");
    b = b.replace(/\s(<3|:\*)/ig, " <img class='emo' alt=':*' src='" + c + "25.gif'\/>");
    b = b.replace(/\s0:\)+/ig, " <img class='emo' alt='0:)' src='" + c + "26.gif'\/>");
    b = b.replace(/\s\^o\^/ig, " <img class='emo' alt='^o^' src='" + c + "27.gif'\/>");
    b = b.replace(/\s:-a/ig, " <img class='emo' alt=':-a' src='" + c + "28.gif'\/>");
    b = b.replace(/\s\*fck\*/ig, " <img class='emo' alt='*fck*' src='" + c + "29.gif'\/>");
    b = b.replace(/\sxV/ig, " <img class='emo' alt='xV' src='" + c + "30.gif'\/>");
    b = b.replace(/\sx\@/g, " <img class='emo' alt='x@' src='" + c + "31.gif'\/>");
    b = b.replace(/\s\X\@/g, " <img class='emo' alt='X@' src='" + c + "32.gif'\/>");
    b = b.replace(/\s:-d/ig, " <img class='emo' alt=':-d' src='" + c + "33.gif'\/>");
    b = b.replace(/\s:-bd/ig, " <img class='emo' alt=':-bd' src='" + c + "34.gif'\/>");
    b = b.replace(/\s\~x\(+/ig, " <img class='emo' alt='~x(' src='" + c + "35.gif'\/>");
    b = b.replace(/\s:W/g, " <img class='emo' alt=':W' src='" + c + "37.gif'\/>");
    b = b.replace(/\s''J/ig, " <img class='emo' alt='&#39;&#39;J' src='" + c + "47.gif'\/>");
    a.innerHTML = b;
} repText('comment-holder');
//]]>
</script>
</b:if>

Klik Simpan Template.

Pembaharuan: Mengganti pola /<tag>(.[^>]*)<\/tag>/ig dan /\[bracket\](.[^\]]*)\[\/bracket\]/ig menjadi /<tag>(.*?)<\/tag>/ig dan /\[bracket\](.*?)\[\/bracket\]/ig untuk meloloskan tag <br> di dalam tag manipulasi.

Penerapan Kode-Kode Manipulasi

Saya memberikan dua pilihan, yaitu menggunakan tag HTML dengan target manipulasi yang diambil berdasarkan atribut rel dan menggunakan kata-kata kunci yang dimasukkan ke dalam braket kotak sebagai penggambaran tag HTML. Saya merekomendasikan Anda untuk menggunakan tag HTML karena mereka masih bisa bekerja tanpa JavaScript (ini juga merupakan standar manipulasi komponen komentar di blog Saya):

Perintah Format
Memasukkan gambar <i rel="image">URL Gambar</i>
[img]URL Gambar[/img]
Memasukkan video YouTube <i rel="youtube">URL YouTube</i>
[youtube]URL YouTube[/youtube]
Memasukkan tag <code> <i rel="code">Kode Anda</i>
[code]Kode Anda[/code]
Memasukkan tag <pre> <i rel="pre">Kode Anda</i>
[pre]Kode Anda[/pre]
Memasukkan kuota <b rel="quote">Kata-kata Anda</b>
[blockquote]Kata-kata Anda[/blockquote]
Memasukkan emotikon Beberapa kode yang bisa digunakan: :) :( =( :s ^_^ :D =D ^:D @@, ;) :-bd :-d :'( :'( T_T :\ :p B) :Q :Ozz 7:( \o/ \m/ <3 0:) ^o^ :-a 7:O *fck* xV x@ X@ ~x( ''J :W

Labels: , , ,

Sunday, May 20, 2012

Cek Apakah Textarea Mengandung Karakter Ganti Baris atau Tidak

Ini adalah masalah yang Saya alami. Mengenai konverter HTML khusus di blog Saya. Sepertinya pengunjung masih belum begitu mengerti bahwa <i rel="code"> dan <i rel="pre"> itu berbeda. Jadi saat mereka mem-paste kode yang seharusnya berada segaris dengan kalimat malah menghasilkan tampilan yang terpotong dengan kalimat:

Contoh Kasus - Kesalahan Konversi
Contoh kasus terbaru: Seharusnya kode <p> yang dituliskan tidak masuk di dalam elemen <pre> melainkan masuk di dalam elemen <code> - Permalink

Dengan beberapa baris kode ini Saya telah berhasil mengatasi masalahnya:

function check() {
    var input = document.getElementById('txt').value;
    if (input.lastIndexOf('\n') != -1) {
        // Mengandung karakter ganti baris
    } else {
        // Tidak mengandung karakter ganti baris
    }
}

Lihat Demo

Intinya adalah, kode ini akan mengecek apakah di dalam textarea mengandung karakter \n (ganti baris) atau tidak. Jika ya, lakukan perintah A. Jika tidak, lakukan perintah B. Dan setelah alat diperbaiki, hasil komentarpun membaik.

HOREEE!!!
HOREEE!!! - Permalink

Kode dimentahkan dari sebuah ide jQuery di sini

Labels: , , , ,

Friday, May 18, 2012

Regex untuk Mendeteksi URL Gambar

/(http:\/\/[\w\-\.]+\.[a-zA-Z]{2,3}(?:\/\S*)?(?:[\w])+\.(?:jpg|png|gif|jpeg|bmp))/ig

Contoh Penerapan: Mengubah URL Gambar menjadi Gambar

Baris kode ini akan mengubah semua pola URL di dalam #comment-holder yang terdeteksi sebagai URL gambar dengan elemen <img> secara otomatis:

var content = document.getElementById('comment-holder').innerHTML;
    content = content.replace(/(http:\/\/[\w\-\.]+\.[a-zA-Z]{2,3}(?:\/\S*)?(?:[\w])+\.(?:jpg|png|gif|jpeg|bmp))/ig, "<img src='$1' alt=''\/>");
document.getElementById('comment-holder').innerHTML = content;

Lihat Demo


Referensi: Regex Replace URL with Links

Labels: , , ,

Tuesday, April 24, 2012

Membuat Sistem Penomoran Otomatis pada Setiap Baris Kode di dalam Tag PRE

Membuat Penomoran Otomatis pada Setiap Baris Kode di dalam Tag PRE

Cara termudah untuk menciptakan baris-baris angka di dalam tag <pre> adalah dengan menghitung jumlah karakter ganti baris di dalamnya, kemudian kita gunakan hasilnya untuk menciptakan deret angka yang nantinya akan mengalir secara otomatis.

Kita mulai dengan markup HTML seperti ini sebagai gambaran awal:

<pre><code>Baris teks 1
Baris teks 2
Baris teks 3</code></pre>

Pertama-tama kita harus menyeleksi semua elemen <pre>:

var pre = document.getElementsByTagName('pre'),
    pl = pre.length;
for (var i = 0; i < pl; i++) {
    // Lakukan sesuatu di sini melalui objek pre[i] ...
}

Setelah itu buat kontainer baris-baris angka dengan elemen <span>:

var pre = document.getElementsByTagName('pre'),
    pl = pre.length;
for (var i = 0; i < pl; i++) {
    // Sisipkan kontainer angka-angka
    pre[i].innerHTML = '<span class="line-number"></span>' + pre[i].innerHTML + '<span class="cl"></span>';
}

Markup HTML saat ini seharusnya sudah menjadi seperti ini:

<pre><span class="line-number"></span><code>Baris teks 1
Baris teks 2
Baris teks 3</code><span class="cl"></span></pre>

Hitung jumlah karakter ganti baris (\n) di dalam masing-masing elemen <pre>. Buat sebuah loop dengan batasan akhir sebanyak/sebesar jumlah karakter ganti baris yang ditemukan untuk membatasi jumlah angka-angka yang masuk ke dalam kontainer angka secara otomatis:

var pre = document.getElementsByTagName('pre'),
    pl = pre.length;
for (var i = 0; i < pl; i++) {
    // Sisipkan kontainer angka
    pre[i].innerHTML = '<span class="line-number"></span>' + pre[i].innerHTML + '<span class="cl"></span>';
    // Hitung jumlah karakter `\n` di dalam tag <pre>
    var num = pre[i].innerHTML.split(/\n/).length;
    for (var j = 0; j < num; j++) {
        // Menangkap elemen <span> pertama / elemen `.line-number`
        var line_num = pre[i].getElementsByTagName('span')[0];
        // Masukkan angka-angka ke dalam kontainer angka melalui elemen <span> baru
        line_num.innerHTML += '<span>' + (j+1) + '</span>';
    }
}

Sekarang markup HTML sudah menjadi seperti ini:

<pre><span class="line-number"><span>1</span><span>2</span><span>3</span></span><code>Baris teks 1
Baris teks 2
Baris teks 3</code><span class="cl"></span></pre>

Sisanya tinggal memposisikan kontainer angka ke bagian samping dengan CSS agar letaknya menjadi berada di sebelah kiri kode-kode yang kita tuliskan di dalam tag <pre>:

pre {
  background-color:#eee;
  overflow:auto;
  margin:0 0 1em;
  padding:.5em 1em;
}

pre code,
pre .line-number {
  /* Ukuran line-height antara teks di dalam tag <code> dan <span class="line-number"> harus sama! */
  font:normal normal 12px/14px "Courier New",Courier,Monospace;
  color:black;
  display:block;
}

pre .line-number {
  float:left;
  margin:0 1em 0 -1em;
  border-right:1px solid;
  text-align:right;
}

pre .line-number span {
  display:block;
  padding:0 .5em 0 1em;
}

pre .cl {
  display:block;
  clear:both;
}

Lihat Demo


Hasil Seluruh Pekerjaan + Dekorasi

HTML

<pre><code> ... </code></pre>

JavaScript

(function() {
    var pre = document.getElementsByTagName('pre'),
        pl = pre.length;
    for (var i = 0; i < pl; i++) {
        pre[i].innerHTML = '<span class="line-number"></span>' + pre[i].innerHTML + '<span class="cl"></span>';
        var num = pre[i].innerHTML.split(/\n/).length;
        for (var j = 0; j < num; j++) {
            var line_num = pre[i].getElementsByTagName('span')[0];
            line_num.innerHTML += '<span>' + (j+1) + '</span>';
        }
    }
})();

CSS

pre {
  background-color:white;
  padding:0 1em;
  white-space:pre;
  word-wrap:normal;
  overflow:auto;
}

pre code,
pre .line-number {
  display:block;
  font:normal normal 13px/24px "Consolas","Bitstream Vera Sans Mono","Courier New",Courier,monospace !important;
  color:#006699;
}

pre .line-number {
  float:left;
  margin:0 1em 0 -1em;
  color:#aaa;
  background-color:#f5f5f5;
  border-right:3px solid #6CE26C;
  text-align:right;
  min-width:2.5em;
}

pre .line-number span {
  display:block;
  padding:0 .5em 0 1em;
}

pre .line-number span:nth-child(even) {background-color:#eee}

pre .cl {
  display:block;
  clear:both;
}

Lihat Demo

Labels: , ,

Monday, April 23, 2012

Bungkus/Pisahkan Setiap Baris Kata dengan Elemen

$('div').each(function() {
    var d = $(this).html();
    $(this).html('<p>' + d.replace(/[\r\n]+(?=[^\r\n])/g, '</p><p>') + '</p>');
});

Kode di atas akan mengubah sekelompok teks yang tadinya seperti ini:

<div>Lorem ipsum
dolor sit amet
consectetuer
adipiscing elit.</div>

menjadi seperti ini:

<div><p>Lorem ipsum</p>
<p>dolor sit amet</p>
<p>consectetuer</p>
<p>adipiscing elit.</p></div>

Lihat Demo

Namun kode di atas hanya berlaku untuk ganti baris berupa \r dan \n. Jika Anda sedang berhubungan dengan ganti baris berupa elemen <br>, Anda bisa menggunakan ini:

$('div').contents().filter(function() {
    // Select all textnodes
    return this.nodeType == 3;
}).wrap('<p></p>'); // Place them inside paragraph elements
$('br', 'div').remove(); // Remove the line-break

Lihat Demo


  1. Stackoverflow - How to Strip Out <br> Tags and Wrap Lines with <p> and </p> Tags?
  2. Stackoverflow - jQuery, Remove New Line Then Wrap Textnodes with <p>

Labels: , , ,

Mengubah URL YouTube menjadi Video

Video
$('p').html(function(i, html) {
    var re  = /(?:http:\/\/)?(?:www\.)?(?:youtube\.com|youtu\.be)\/(?:watch\?v=)?(.+)/g,
        vid = '<iframe width="420" height="345" src="//www.youtube.com/embed/$1" allowfullscreen></iframe>';
    return html.replace(re, vid);
});

Lihat Demo

Lolos untuk dua bentuk URL YouTube seperti ini:

http://youtu.be/-joKveiaabA
http://www.youtube.com/watch?v=-joKveiaabA

Sumber: How to Convert a YouTube Video URL to the Iframe Embed Code, using jQuery

Labels: , , ,

Sunday, April 22, 2012

JQuery Highlight Text Plugin

jQuery.fn.highlight = function(str, className) {
    var regex = new RegExp(str, "gi");
    return this.each(function() {
        $(this).contents().filter(function() {
            return this.nodeType == 3 && regex.test(this.nodeValue);
        }).replaceWith(function() {
            return (this.nodeValue || "").replace(regex, function(match) {
                return "<span class=\"" + className + "\">" + match + "</span>";
            });
        });
    });
};

Penggunaan

Seleksi sebuah elemen kemudian terapkan fungsi .highlight("teks", "nama-kelas"):

$('p').highlight("lorem ipsum", "yellow");

Lihat Demo


Sumber: A Web Coding Blog - Highlight Words in Text with jQuery

Labels: , , ,

Thursday, April 19, 2012

Optimasi Thumbnail pada Auto Read-More Link dan Widget Blogger

Ini adalah auto read-more link script yang biasa Anda gunakan untuk mengubah posting asli menjadi ringkasan posting:

<script>
var summary_noimg    = 300,
    summary_img      = 300,
    img_thumb_height = 100,
    img_thumb_width  = 120;
</script>
<script>
//<![CDATA[
/**
 * =======================================================================
 * Auto-readmore link script, version 2.0 (for blogspot) (C)2008 by Anhvo
 * =======================================================================
 */
function removeHtmlTag(strx, chop) {
    if (strx.indexOf("<") != -1) {
        var s = strx.split("<");
        for (var i = 0; i < s.length; i++) {
            if (s[i].indexOf(">") != -1) {
                s[i] = s[i].substring(s[i].indexOf(">") + 1, s[i].length);
            }
        }
        strx = s.join(" ");
    }
    chop = (chop < strx.length - 1) ? chop : strx.length - 2;
    while (strx.charAt(chop - 1) != ' ' && strx.indexOf(' ', chop) != -1) chop++;
    strx = strx.substring(0, chop - 1);
    return strx + '...';
}

function createSummaryAndThumb(pID) {
    var div = document.getElementById(pID);
    var imgtag = "";
    var img = div.getElementsByTagName("img");
    var summ = summary_noimg;
    if (img.length >= 1) {
        imgtag = '<span style="float:left;padding:0px 10px 5px 0px;"><img alt="" src="' + img[0].src + '" width="' + img_thumb_width + 'px" height="' + img_thumb_height + 'px"/></span>';
        summ = summary_img;
    }
    var summary = imgtag + '<div>' + removeHtmlTag(div.innerHTML, summ) + '</div>';
    div.innerHTML = summary;
}
//]]>
</script>

Merasa ada yang aneh dengan itu? Saya rasa tidak. Tapi jika Anda sedikit lebih jeli dan memasuki cara kerjanya lebih dalam, maka Anda akan mengerti beberapa hal:

  • Pertama, script tersebut akan mengurangi jumlah karakter posting yang panjang menjadi lebih pendek sesuai dengan pengaturan pada variabel summary_noimg dan summary_img
  • Ke dua, script tersebut akan menampilkan sebuah gambar mini/thumbnail yang diambil dari gambar pertama pada posting terkait. Ukurannya juga berubah, menjadi lebih kecil. Dalam contoh di atas ukurannya dapat diketahui akan berubah menjadi 120 × 100 piksel (nilainya ada pada variabel img_thumb_width dan img_thumb_height).

Itu berarti bahwa jika kita menerapkan fitur auto-readmore-link pada blog kita, maka kita dapat mempercepat proses muat halaman blog, karena kita pikir kita telah mengubah paragraf posting yang panjang menjadi lebih pendek. Dan bahkan, ukuran gambar telah diperkecil menjadi 120 × 100 piksel.

Tapi kenapa saat Anda mencoba merasakan proses muat halaman blog Anda rasanya tidak ada perbedaan yang terlalu jauh antara kecepatan muat posting yang asli dengan versi yang sudah diringkas?

JavaScript Hanya Memanipulasi, Bukan Mengurangi

Script auto read-more link tidak mengurangi ukuran file posting, tapi hanya memanipulasi tampilannya pada pandangan mata. Jika Anda melihat kode sumber dari halaman blog Anda, maka Anda akan melihat bahwa keseluruhan isi posting sebenarnya masih tetap ada pada tempatnya dan ditransfer secara penuh. JavaScript bertugas untuk mengambil beberapa karakter saja dan menampilkannya dalam bentuk ringkasan. Sementara posting yang asli akan ditindih dengan ringkasan yang telah dibuat:

// Menyisipkan summary (duplikat/clone posting yang telah dimanipulasi)
// ke dalam posting dengan ID yang diambil dari <data:post.id/>
var div = document.getElementById(pID);
...
var summary = imgtag + '<div>' + removeHtmlTag(div.innerHTML, summ) + '</div>';
...div.innerHTML = summary;

Sejauh ini tidak ada yang bisa kita lakukan dengan ringkasan posting. Yang bisa kita lakukan hanyalah mengoptimasi ukuran thumbnail. Perlu diketahui bahwa meskipun ukuran gambar pada posting read-more Anda sudah menjadi lebih kecil dari sebelumnya, tapi sebenarnya yang berubah hanya ukuran tinggi dan lebarnya saja, sedangkan ukuran gambar masih tetap sama besarnya dan sama beratnya. Coba Anda klik kanan pada salah satu thumbnail posting kemudian klik View Image Info:

View Image Info
Menampilkan info gambar

dari situ Anda akan melihat ukuran gambar aslinya, bukan hanya ukuran lebar dan tinggi gambar asli, tapi juga ukuran file dari gambar tersebut:

Lebih Besar
Ukuran gambar jauh lebih besar dari yang terlihat

NAH! Ternyata thumbnail kecil yang Anda lihat sebagai gambar berukuran 120 × 100 piksel adalah gambar berukuran 495 × 371 piksel. Dan bukan itu saja, coba lihat pada file size: 24.75KB! Untuk ukuran gambar sebesar itu, kenapa harus dipaksakan menjadi berukuran 120 × 100? Lalu, bisakah kita memperkecil ukuran gambar tersebut secara nyata, dan bukan hanya sekedar menekan ukuran lebar dan tinggi gambar menggunakan atribut width dan height?

Picasa memiliki cara yang unik dalam mengompres gambar. Mereka mengambil ukuran gambar dari URLnya (yaitu kode-kode seperti /s200, /s400, /s1600, /s40-c dan yang lainnya). Dari path itulah Picasa akan mentransfer ukuran gambar dengan resolusi sesuai dengan kode ukuran yang tercantum.

Blogger menggunakan fasilitas yang sama, jadi kita bisa menggunakan kunci sederhana itu untuk memperkecil gambar. Berikut ini adalah beberapa contoh ukuran bawaan dari editor posting pada Blogger seperti Small, Medium, Large, X-Large dan Original Size (Tapi sebenarnya Anda juga masih bisa menentukan ukurannya sendiri):

Kode Ukuran Contoh URL
/s72-c Media Thumbnail (Ukuran Persegi) https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHHxb-mBFKOhVNIK69q7tK4ezGSVLLYu8BiVJ3unORkUjR2pqMjakSrWe_2qEVLUzXezGScsSwGelq-MRxZywN0tjmJpFaU0FYbkflXXDR2Jp01NQezWgiKhmRSetgebIEuh5fgVvAi2w/s72-c/319.jpg
/s200 Small https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHHxb-mBFKOhVNIK69q7tK4ezGSVLLYu8BiVJ3unORkUjR2pqMjakSrWe_2qEVLUzXezGScsSwGelq-MRxZywN0tjmJpFaU0FYbkflXXDR2Jp01NQezWgiKhmRSetgebIEuh5fgVvAi2w/s200/319.jpg
/s320 Medium https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHHxb-mBFKOhVNIK69q7tK4ezGSVLLYu8BiVJ3unORkUjR2pqMjakSrWe_2qEVLUzXezGScsSwGelq-MRxZywN0tjmJpFaU0FYbkflXXDR2Jp01NQezWgiKhmRSetgebIEuh5fgVvAi2w/s320/319.jpg
/s400 Large https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHHxb-mBFKOhVNIK69q7tK4ezGSVLLYu8BiVJ3unORkUjR2pqMjakSrWe_2qEVLUzXezGScsSwGelq-MRxZywN0tjmJpFaU0FYbkflXXDR2Jp01NQezWgiKhmRSetgebIEuh5fgVvAi2w/s400/319.jpg
/s640 X-Large https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHHxb-mBFKOhVNIK69q7tK4ezGSVLLYu8BiVJ3unORkUjR2pqMjakSrWe_2qEVLUzXezGScsSwGelq-MRxZywN0tjmJpFaU0FYbkflXXDR2Jp01NQezWgiKhmRSetgebIEuh5fgVvAi2w/s640/319.jpg
/s1600 Original Size https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHHxb-mBFKOhVNIK69q7tK4ezGSVLLYu8BiVJ3unORkUjR2pqMjakSrWe_2qEVLUzXezGScsSwGelq-MRxZywN0tjmJpFaU0FYbkflXXDR2Jp01NQezWgiKhmRSetgebIEuh5fgVvAi2w/s1600/319.jpg

Semua tautan gambar di atas sebenarnya sama. Saya hanya membedakan pada bagian yang berwarna jingga. Namun saat Anda mencoba mengeceknya, ternyata hanya dengan mengubah URL tersebut saja sudah bisa memperkecil ukuran gambar. Pada awalnya Saya sempat berpikir bahwa saat kita mengunggah gambar ke Picasa, maka Picasa akan menyimpan semua gambar yang sama tersebut dalam berbagai ukuran ke dalam folder bernama s200, s400 dan seterusnya. Tapi semua orang tahu bahwa Google tidak sebodoh itu » https://developers.google.com/speed/docs/best-practices/payload#ScaleImages

Posting blog kita memiliki ukuran gambar yang berbeda-beda, bagaimana kita bisa memperkecil ukuran thumbnail tanpa harus memperkecil ukuran gambar pada posting?

Caranya sederhana. Kita cukup mengubah URL thumbnail yang tadinya berada di seputar /s400, /s640 dan /s1600 menjadi ukuran yang lebih kecil seperti ini:

imgtag = '<span style="float:left;padding:0px 10px 5px 0px;"><img alt="" src="' + img[0].src.replace(/\/s(320|400|640|1600)/, "\/s200") + '" width="' + img_thumb_width + 'px" height="' + img_thumb_height + 'px"/></span>';

dan agar pengaturan ukuran menjadi jauh lebih mudah, lebih baik set karakter pengganti berdasarkan variabel lebar thumbnail:

imgtag = '<span style="float:left;padding:0px 10px 5px 0px;"><img alt="" src="' + img[0].src.replace(/\/s(320|400|640|1600)/, "\/s" + img_thumb_width) + '" width="' + img_thumb_width + 'px" height="' + img_thumb_height + 'px"/></span>';

Dengan cara di atas maka ukuran thumbnail bisa diperkecil sampai dua kali lipatnya. Bahkan lebih!

Gambar sudah mengecil
Ukuran gambar mengecil sampai 2 kali lipat

Saran Saya untuk Developer Blogger

Meskipun tulisan panjang ini hanya membicarakan seputar thumbnail auto read-more link blogspot, tapi sebenarnya bukan itu inti dari apa yang ingin Saya sampaikan. Jika Anda adalah seorang pembuat widget Blogger, Saya harap Anda bersedia untuk memulai mengubah sedikit cara Anda memperkecil gambar. Ini adalah saran terbaik dari Saya. Jika Anda menciptakan widget dengan ukuran lebar dan tinggi thumbnail yang telah diset di dalam variabel, jangan lupa juga untuk menerapkan variabel tersebut sebagai pengganti URL gambar, sehingga kecepatan muat gambar pada widget juga bisa ditingkatkan:

var thumbWidth  = 200,
    thumbHeight = 100;

// Kode widget Anda....
document.write('<img src="' + postimg.replace(/\/s(320|400|640|1600)/, "\/s" + thumbWidth) + '" width="' + thumbWidth + '" height="' + thumbHeight + '" alt="thumbnail" />');

Mengenai ringkasan posting, Saya harap suatu saat nanti Blogger akan merilis tag <data> khusus untuk memanggil ringkasan posting, sama seperti halnya dalam pembagian opsi feed yang sudah ada.

Konsepnya kira-kira begini:

Feed Blog

Dengan begitu kita tidak perlu lagi repot-repot menuliskan JavaScript yang rumit untuk menciptakan posting read-more. Yang perlu kita lakukan hanyalah sesuatu yang sederhana seperti ini:

<article class='post-body entry-content'>
  <b:if cond='data:blog.pageType == &quot;static_page&quot;'>
    <data:post.body/>
  <b:else/>
    <b:if cond='data:blog.pageType != &quot;item&quot;'>
      <div expr:id='data:post.id'><data:post.bodySummary/>      </div>
      <div class='alignright'>
        <a class='read-more' expr:href='data:post.url' rel='dofollow'>READ MORE</a>
      </div>
    </b:if>
    <b:if cond='data:blog.pageType == &quot;item&quot;'>
      <data:post.body/>
    </b:if>
  </b:if>
  <div class='clear'/>
</article>

Pembaharuan: 28 April 2012

Blogger sudah memiliki tag <data> yang bisa menampilkan ringkasan posting meski jumlahnya masih sangat terbatas:

<data:post.snippet/>

Elemen ini sebenarnya lebih sering kita jumpai pada widget Posting Populer yang biasa digunakan untuk menampilkan ringkasan pendek di sekitar thumbnail. Selengkapnya mengenai implementasi auto read-more tanpa JavaScript dengan memanfaatkan tag <data:post.snippet/> dapat Anda baca pada salah satu posting dari seseorang di Vietnam » Auto readmore không s? d?ng javascript cho Blogger


Ikon: ArtDesigner

Labels: , , , ,

Monday, April 16, 2012

LetteringJS Sederhana

LetteringJS
http://letteringjs.com

Pikiran Saya terbuka saat System of Blog menanyakan sesuatu tentang cara membagi-bagi setiap huruf dengan jQuery untuk kemudian dibungkus dengan elemen <span>. Ternyata untuk menciptakan manipulasi teks seperti LetteringJS bisa dengan mudah dibuat. Saya mendapatkan konsep ini dari Stackoverflow - Wrap Each Char in Except Tags with jQuery:

// Bungkus semua huruf dengan elemen span
$('.splitWord').children().andSelf().contents().each(function() {
    if (this.nodeType == 3) {
        $(this).replaceWith(
            $(this).text().replace(/(\w)/g, "<span class='char'>$&</span>")
        );
    }
});

// Menambahkan kelas `.char1`, `.char2`, `.char3`, ...
$('.splitWord').each(function() {
    $('span.char', this).each(function(i) {
        i = i+1;            
        $(this).addClass('char' + i);
    });
});

Lihat Demo

Cara kerja kode bagian pertama adalah akan memecah setiap huruf kemudian mengelilinginya dengan elemen <span> seperti ini:

<p class="splitWord">
    <span class="char">L</span>
    <span class="char">o</span>
    <span class="char">r</span>
    <span class="char">e</span>
    <span class="char">m</span>
</p>

Dan bagian ke dua bertugas untuk menambahkan kelas-kelas baru yang lebih spesifik dan berbeda satu sama lain:

<p class="splitWord">
    <span class="char char1">L</span>
    <span class="char char2">o</span>
    <span class="char char3">r</span>
    <span class="char char4">e</span>
    <span class="char char5">m</span>
</p>

Sama persis seperti LetteringJS.

Labels: , ,