Forum Moderators: coopster & phranque

Message Too Old, No Replies

Shuffling HTML

any ideas?

         

okephoto

11:08 pm on Jun 27, 2004 (gmt 0)

10+ Year Member



I've been looking for a simple script that will take HTML fragments or .txt files and randomly shuffle them on a page where all the files have to be included but not repeated.

So far, any of the solutions I'm finding will only randomly place one fragment in an area rather than shuffling the data.

An example with 3 .txt files:

<table><tr><td>
1.txt
</td></tr></table>

<table><tr><td>
2.txt
</td></tr></table>

<table><tr><td>
3.txt
</td></tr></table>

if reloaded:

<table><tr><td>
3.txt
</td></tr></table>

<table><tr><td>
1.txt
</td></tr></table>

<table><tr><td>
2.txt
</td></tr></table>

etc.

Any ideas would be wondful. If programming is needed would consider offers.

Thanks

davidpbrown

8:35 am on Jun 28, 2004 (gmt 0)

10+ Year Member



XSLT is designed to manipulate XML (=~HTML+), the difficulty is generating a random seed.

With an XSLT processor you might use a date:time function as seed but as yet this isn't avaliable in the basic IE processor for XSLT.

What follows links an XSL transform to the input xml file which holds filenames and then sorts the filenames using what appears to be a psuedo-random function suggested here [xslt.com].

Save the files in the same directory and throw the xml file into IE to see the end result.

File random.xml

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="randomOutput.xsl"?>
<files>
<filename>somefilea1.txt</filename>
<filename>asaaa2.txt</filename>
<filename>ascftsw3.txt</filename>
</files>

File randomOutput.xsl

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:variable name="seed">3</xsl:variable>
<html>
<body>
<xsl:for-each select="files/filename">
<xsl:sort select="substring(substring-after($seed div (position() * string-length()), '.'),2, 3)" data-type="number" />
<table><tr><td>
<xsl:value-of select="."/>
</td></tr></table>
</xsl:for-each>
</body>
</html>
</xsl:template>
<xsl:template match="text()¦@*">
</xsl:template>
</xsl:stylesheet>

I don't know whether there is a better initial seed value than 3.

The downside to not having a dynamic seed is that you get the same result until the input is changed again. This especially might not work well if your filenames are very similar.

It might be possible to add a PHP script to insert an ~truely random initial seed value, instead of '3', but then it may be simpler to do the whole thing in Perl or PHP, I don't know.

HTH

VectorJ

2:59 pm on Jun 28, 2004 (gmt 0)

10+ Year Member



This assumes that the text files are named 1.txt, 2.txt, and 3.txt. For a larger number of files, change the value of $total_file_num. If the .txt files are not in the same directory, you'll need to change the path to the file in the "open" function. There's probably a more elegant way to do this, but....


my $total_file_num = 3;
my $ret = "";
for ($i=1; $i<=$total_file_num; $i++) {
$files{$i} = 1;
}
while (scalar(keys %files) > 0) {
$file_num = int(rand $total_file_num);
@file_names = keys %files;
open (F, $file_names[$file_num] . '.txt');
while (<F>) {
$ret .= $_;
}
close (F);
delete $files{$file_names[$file_num]};
$total_file_num--;
}
print $ret;

timster

5:47 pm on Jun 28, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Maybe something like this?

my @array = ('1.txt','2.txt','3.txt','4.txt','5.txt','6.txt');
my @newOrder = ();
while (@array)
{ push(@newOrder, splice(@array, int(rand() * $#array), 1)) }
print "@newOrder";

VectorJ

7:42 pm on Jun 28, 2004 (gmt 0)

10+ Year Member



Yeah, I'm gonna have to go ahead and say that timster's code is much better than mine. And thanks to timster for teaching me how to use splice().

okephoto

3:20 am on Jun 29, 2004 (gmt 0)

10+ Year Member



Thanks all,

I'll give this a try in the next day or so.