Compare commits

..

10 Commits

Author SHA1 Message Date
Jacob Haddon
6a2177739a cleaned up the code of books.pl; let's not talk about the previous code 2024-03-17 20:37:57 -04:00
Jacob Haddon
697aff0b8d updated books.pl to have variables for file names; changed the js variable names; updated index.html to match changes 2024-03-17 19:57:37 -04:00
Jacob Haddon
ccde468e88 fixed date in meta copy, clean up some text 2024-03-17 11:30:26 -04:00
Jacob Haddon
d5361e391e it is a mess, but it works, makes one file with the books in pages, makes a second with a year's worth of pages at random.
todo: check no repeats, clean up the code.
2024-03-13 21:53:51 -04:00
Jacob Haddon
6f42818518 adds loop to go through multiple books 2024-03-13 20:05:34 -04:00
Jacob Haddon
973dc8e8f5 toggles blackout button on reset; attempting to fix buttons on iOS 2024-03-13 07:42:14 -04:00
Jacob Haddon
a8c87ec87e updated screenshot filename to add the date and time 2024-03-12 21:47:28 -04:00
Jacob Haddon
faaeb2633b code cleanup 2024-03-12 21:16:51 -04:00
Jacob Haddon
e52846a08f updated font css, hover css 2024-03-12 20:19:49 -04:00
Jacob Haddon
83c918809b more styling on the page 2024-03-11 20:52:06 -04:00
4 changed files with 322 additions and 207 deletions

View File

@ -15,6 +15,7 @@ this takes a "page" from a book and let's you make a blackout poem which you can
## Perl
* File::Slurp - https://metacpan.org/pod/File::Slurp (Perl)
* JSON - https://metacpan.org/pod/JSON (Perl)
## Font
@ -23,3 +24,10 @@ The font is Lora - https://github.com/cyrealtype/Lora-Cyrillic (OFL)
## Texts
texts are public domain from Project Gutenberg - https://www.gutenberg.org/
* Wuthering Heights - https://www.gutenberg.org/ebooks/768
* Jane Eyre - https://www.gutenberg.org/ebooks/1260
* Agnes Grey - https://www.gutenberg.org/ebooks/767
* Northanger Abbey - https://www.gutenberg.org/ebooks/121

217
books.pl
View File

@ -5,7 +5,10 @@ use 5.010;
use strict;
use warnings;
use File::Slurp; # https://metacpan.org/pod/File::Slurp
use JSON;
use JSON; # https://metacpan.org/pod/JSON
use Time::Piece; # https://perldoc.perl.org/Time::Piece
use DateTime;
###################################
#
@ -16,137 +19,185 @@ use JSON;
# splitting them up into "pages" for easier display
#
# license GPLv3.0 https://www.gnu.org/licenses/gpl-3.0.en.html
# Code repository:
#
# Code repository: https://code.jacobhaddon.com/jake/dbpc
# Written by Jacob Haddon https://jacobhaddon.com
#
# This uses File::Slurp - https://metacpan.org/pod/File::Slurp
# This uses
# * File::Slurp - https://metacpan.org/pod/File::Slurp
# * JSON - https://metacpan.org/pod/JSON
#
# Texts are from Project Gutenburg - https://www.gutenberg.org/
#
###################################
my $json = new JSON;
my %books = (
title => "Wuthering Heights",
author => "Emily Bronte",
url => "https://www.gutenberg.org/ebooks/768",
file => "books/wutheringheights.txt"
); # books hash
# print($books{'file'});
# read in a whole file into a scalar
my $book = read_file($books{'file'});
my @chapters = split('\nCHAPTER', $book);
my $test = @chapters;
print($test);
# While these have json formatting, they are JS files
my $complete_books_js = "complete_books.js";
my $book_pages_js = "book_pages2.js";
# number of lines in a page
my $number_of_lines = 31;
my $j = 0;
my @page_text;
foreach (@chapters) {
# print($j);
# how many pages do you want made?
my $number_of_pages = 365;
my @books = (
{
title => "Wuthering Heights",
author => "Emily Bronte",
url => "https://www.gutenberg.org/ebooks/768",
file => "books/wutheringheights.txt",
chapter_marker => "CHAPTER"
},
{
title => "Jane Eyre",
author => "Charlotte Bronte",
url => "https://www.gutenberg.org/ebooks/1260",
file => "books/janeeyre.txt",
chapter_marker => "CHAPTER"
},
{
title => "Agnes Grey",
author => "Anne Bronte",
url => "https://www.gutenberg.org/ebooks/767",
file => "books/agnesgrey.txt",
chapter_marker => "CHAPTER"
}
); # books hash
my $json = new JSON;
###################################
# Make the books into pages
###################################
my $k = 0;
foreach (@books) {
# read in a whole file into a scalar
my $book = read_file($books[$k]{'file'});
# split the book into chapters by the appropriate marker
my @chapters = split('\n' . $books[$k]{'chapter_marker'}, $book);
# go through each chapter and make pages based on number of desired lines
my $j = 0;
my @page_text;
foreach (@chapters) {
my @chapter_lines = split(/\r\n/, $chapters[$j]);
if ($j != 0){
$chapter_lines[0] = "<h1>CHAPTER" . $chapter_lines[0] . "</h1>\n\n<p>";
}
} # if j != 0
# how many lines are in the whole chapter
my $chapter_length = @chapter_lines;
my $test2 = @chapter_lines;
# print ($test2);
my $i = 0;
# this is the starting place for the splice
my $line_number = $number_of_lines * $i;
while($line_number < $test2) {
# print($line_number);
# print($i);
# while the line number is still less than the number of lines in the chapter; make a page
while($line_number < $chapter_length) {
# print($chapter_lines[6]);
my @page = splice(@chapter_lines, 0, $number_of_lines);
# print($page[22]);
# add a starting paragraph marker for the first page
$page[0] = "<p>" . $page[0];
# ad in blank space
foreach (@page) {
if ($_ eq "") {
$_ = "</p>\n\n<p>";
}
} # foreach page
# join the pages by a space into a string
$page_text[$j][$i] = join(" ", @page);
# Add trailing paragraph marker
$page_text[$j][$i] = $page_text[$j][$i] . "</p>\n\n";
#iterate
$i++;
$line_number = $number_of_lines * $i;
} # while line number
# iterate
$j++;
} # foreach chapters
# print($i);
# $i++;
# my @chapter_lines = split(/[\n|\r]/, $_);
# print($chapter_lines[0]);
$books[$k]{'pages'} = \@page_text;
# iterate
$k++;
} # foreach chapters
} # foreach books
$books{'pages'} = \@page_text;
###################################
# Make a complete_books_js file
###################################
my @tst_page = @{$books{'pages'} };
#turn the books variable into a JSON string
my $json_text = $json->pretty->encode( \@books );
# print($tst_page[12][0]);
# my $json_text = encode_json(\%books);
my $json_text = $json->pretty->encode( \%books );
my $js_text = "let book = " . $json_text;
# make the JSON formatted text into a Javascript object
my $js_text = "let books = " . $json_text;
# write the file
open(FH, '>', "test3.js") or die $!;
open(FH, '>', $complete_books_js) or die $!;
print FH $js_text;
close(FH);
# print($page_text[12][0]);
###################################
# make a list of 365 pages
###################################
# print($books{'pages'});
my $for = @books;
my %page_list;
my $dt = DateTime->now();
# print($chapters[1]);
# my @chapter_lines = split(/\r\n/, $chapters[1]);
# $chapter_lines[0] = "<h1>Chapter" . $chapter_lines[0] . "</h1>\n\n<p>";
for ( my $l; $l < $number_of_pages; $l++){
# get a random book
my $book_list = int(rand($for));
# get the number of chapters in the book
my $chapter_list = @{$books[$book_list]{'pages'}};
# pull out a random chapter from that book
my $chapter_select = int(rand($chapter_list));
# get the number of pages in the chapter
my $page_list = @{$books[$book_list]{'pages'}[$chapter_select]};
# pull out a random page from the chapter
my $page_select = int(rand($page_list));
# get the text of that page
my $page_rand = $books[$book_list]{'pages'}[$chapter_select][$page_select];
$page_list{$dt->ymd} = {
title => $books[$book_list]{'title'},
author => $books[$book_list]{'author'},
page => $page_rand
};
$dt->add(days => 1);
} # for l
###################################
# Make a books_pages_js file
###################################
# made the page_ist into a JSON string
my $json_text2 = $json->pretty->encode( \%page_list );
# make the JSON formatted text into a Javascript object
my $js_text2 = "let book_pages = " . $json_text2;
# write the file
open(FH, '>', $book_pages_js) or die $!;
print FH $js_text2;
close(FH);
# my $test2 = @chapter_lines;
# print ($test2);
#
# my $line_number = 31 * $i;
#
# while($line_number < $test2) {
# print($line_number);
# print($i);
#
# # print($chapter_lines[6]);
# my @page = splice(@chapter_lines, 0, 31);
# # print($page[22]);
#
# foreach (@page) {
# if ($_ eq "") {
# $_ = "</p>\n\n<p>";
# }
# } # foreach page
#
# $page_text[$i] = join("", @page);
# $page_text[$i] = $page_text[$i] . "</p>\n\n";
#
# $i++;
# $line_number = 31 * $i;
#
# }
#
# print($page_text[1]);
# FIN

View File

@ -4,6 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Daily Blackout Poetry Challenge</title>
<!--
@ -30,13 +31,12 @@ this file uses:
-->
<link rel="stylesheet" href="style.css">
<script src="jquery-3.7.1.min.js"></script>
<script src="html2canvas.min.js"></script>
<script src="FileSaver.min.js"></script>
<script src="test3.js"></script>
<script src="book_pages.js"></script>
<script>
@ -44,72 +44,102 @@ this file uses:
// console.log(book.pages[14][6]);
$(document).ready(function(){
// let text = $("#spina").html().split(" ");
// console.log(text);
// get today and format
const today = new Date(Date.now());
let day = today.getDate();
let formattedday = day.toLocaleString('en-US', {
minimumIntegerDigits: 2,
useGrouping: false
});
let month = today.getMonth() + 1;
let formattedmonth = month.toLocaleString('en-US', {
minimumIntegerDigits: 2,
useGrouping: false
});
let year = today.getFullYear();
// console.log(day);
// console.log(formattedmonth);
// make the date string match the book.json file
let todayString = year + "-" + formattedmonth + "-" + formattedday;
// console.log(todayString);
//
// console.log(book[todayString]);
// Make the header with the book info
$("#poem_header").html("<h2>" + book.title + "</h2>\n\n<h3>" + book.author + "</h3>\n");
$("#poem_header").html("<h2>" + book_pages[todayString].title + "</h2>\n\n<h3>" + book_pages[todayString].author + "</h3>\n");
// Add in the page, change the underscores to italics
$("#spina").html(book.pages[14][6].replace(/(_([a-z0-9]+)_)/ig, "<i>$2</i>"));
// $("#spina").html(book.pages[14][6].replace(/(_([a-z0-9]+)_)/ig, "<i>$2</i>"));
$("#spina").html(book_pages[todayString].page.replace(/(_([a-z0-9]+)_)/ig, "<i>$2</i>"));
// format the text with span tags
$("#spina p").each(function( index ) {
let text = $( this ).html().split(" ");
let newText = [];
$.each( text , function(index, value ){
newText[index] = "<span>" + value + "</span>";
// console.log("index:" + index + " <span>" + value + "</span>")
}); // each text
$( this ).html(newText.join(" "));
// console.log(newText.join(" "));
}); // each p
$("#spina p span").each(function( index ) {
}); // each p
// lock the page to prevent edits
$("#lock").click(function(){
$("#spina").toggleClass("unlock");
}); // lock button click
$("#screen").click(function(){
// make a screenshot
$("#screen").click(function() {
// get the date and format the filename
const today = new Date(Date.now());
let day = today.getDate();
let month = today.getMonth() + 1;
let year = today.getFullYear();
let minutes = today.getMinutes();
let hours = today.getHours();
let fileName = "dbpc_" + year + "_" + month + "_" + day + "_" + hours +"-" + minutes + ".png";
// make the screenshot
html2canvas(document.getElementById('poem'), {
scale: 3
}).then(function(canvas) {
// Export the canvas to its data URI representation
// var base64image = canvas.toDataURL("image/png");
//
// // Open the image in a new window
// window.open(base64image , "_blank");
// Export canvas as a blob
canvas.toBlob(function(blob) {
// Generate file download
window.saveAs(blob, "yourwebsite_screenshot.png");
window.saveAs(blob, fileName);
});
});
}); // screen button click
// change for composition view
$("#compose").click(function(){
$("#blackout").click(function() {
$("#spina").toggleClass("unlock");
$("#spina").toggleClass("done");
$( "#spina p span.click" ).toggleClass("clickDone");
$("#spina p span.click").toggleClass("clickDone");
// get today and format
const today = Date(Date.now());
todayFormatted = today.toString();
$("#byline").html("<p>blackout poem inspired by " + book.title + " by " + book.author + "</p><p>composed on: " + todayFormatted) + "</p>";
}); // compose
// add the byline
$("#byline").html("<p>blackout poem inspired by " + book_pages[todayString].title + " by " + book_pages[todayString].author + "</p><p>composed on: " + todayFormatted) + "</p>";
// toggle the text on the button
$(this).text(function(i, text) {
return text === "Blackout!" ? "Un-Blackout!": "Blackout!";
});
}); // blackout button click
// reset everything back
$("#clear").click(function(){
$("#spina").removeClass("done");
$( "#spina p span.click" ).removeClass("click");
$("#spina p span.click").removeClass("click");
$("#byline").html("");
$("#poem_list").html("");
$("#spina").addClass("unlock");
}); // clear
// $("help").hide();
$("#blackout").text("Blackout!");
}); // clear button click
// show help section
$(".helpbtn").click(function(){
@ -122,25 +152,31 @@ $(document).ready(function(){
}); // copy text
$("#copy_text_meta").click(function(){
// get today and format it
const today = Date(Date.now());
todayFormatted = today.toString();
var poem_meta = "#dailyBlackoutPoetryChallenge\n\n" + $("#poem_list").text() + "\n\n" + book.title + " - " + todayFormatted;
navigator.clipboard.writeText(poem_meta);
}); // copy text
// add the meta to the copyed text
var poem_meta = "#dailyBlackoutPoetryChallenge\n\n" + $("#poem_list").text() + "\n\n" + book_pages[todayString].title + " - " + todayFormatted;
navigator.clipboard.writeText(poem_meta);
}); // copy text w/meta
// change the color of a clicked word; add/remove clicked word to list
$(document).on('click', "#spina.unlock p span", function(e){
// $("#spina.unlock p span").click(function(){
// add the class to the clicked word
$( this ).toggleClass("click");
// make the list of words
let list = "";
$("#spina p span.click").each(function(index) {
list += " " + $(this).text();
}); //poem
// Add to the list, but strip out punctuation
// console.log(list.replace(/[^a-z0-9 ]+/ig, ""));
$("#poem_list").html(list.replace(/[^a-z0-9 ]+/ig, ""));
}); //spina click
}); // document ready
</script>
@ -151,69 +187,48 @@ $(document).ready(function(){
<header>
<h1>Daily <span class="purple">Blackout</span> Poetry Challenge</h1>
<p>Your daily blackout poetry challenge! Make a poem, save the poem, share the poem! (Tag the poem: #dailyBlackoutPoetryChallenge)</p>
<p>Your daily blackout poetry challenge! Make a poem, save the poem, share the poem!</p>
<p>Tag the poem: #dailyBlackoutPoetryChallenge</p>
<p>Click on a word to select it, click on it again to unselect. When youve found your poem hit Blackout! Get a screen shot and copy the words below!</p>
</header>
<div id="poem_header"></div>
<nav>
<button class="helpbtn">Help</button> - <button id="lock">Lock</button> - <button id="compose">Blackout!</button> - <button id="clear">Start Over</button> - <button id="screen">Save as image</button>
<button class="helpbtn btn btn-mn">Help</button> - <button id="clear" class="btn btn-mn">Start Over</button> - <button id="blackout" class="btn btn-mn">Blackout!</button> - <button id="screen" class="btn btn-mn">Save as image</button>
</nav>
<div id="poem_header">
<h2>Invaders from the Dark</h2>
<h3>Greye La Spina</h3>
</div>
<main id="poem">
<div id="spina" class="unlock">
<p>I ascertained that Miss Delorme was a responsible person, quite able and willing to defray the costs of printing her book, in case it proved to be out of the line of the regular publishing houses. I arranged to visit her home on June 18th, an easy matter, as I found I could get there by subway. On June 18th, therefor, I walked across the fields to the great wall which she had described in her letters, and rang the bell of the bronze gate. From that moment, I began to realize what Miss Delorme meant when she wrote that she feared for the safety of her manuscript. </p>
<p>Even as I stood there waiting, things started to happen in a most bewildering fashion. I heard somebody throw up a window on a side of the house (to my right), and then there came a woman&#8217;s scream, which sounded to me more angry than fearful. The scream was followed by a heavy, metallic clang upon the pavement just around the corner from where I stood. I left the gate and ran in the direction of the noise. </p>
<p>On the sidewalk lay a black tin box as is often used to preserve papers of importance. It was dented badly where it had struck the pavement. I picked it up and then turned my eyes toward the windows above me. </p>
<p>And elderly woman stood at the open window nearest the corner of the house, holding with both hands to the window-frame at either side of her. Although she appeared to be alone, I received a strong impression that she was being pulled from behind, for she was struggling as if with all her power to maintain her position there. As I looked up, the tin box in my hand, she called to me anxiously. </p>
<p>&#8220;Who are you?&#8221;</p>
<p>I told her. </p>
<p>&#8220;Thank God you came in time!&#8221; She cried excitedly. &#8220;Take the box and get away from her as quickly as you can. Don&#8217;t let it out of your sight until it has been printed and the books distributed. You&#8217;ll understand why, when you&#8217;ve read it. Never mind about me! My work is done!&#8221;</p>
<p>As the last words were flung down at me, she disappeared backward into the room, as if pulled there by invisible hands. </p>
</div>
<div id="spina" class="unlock"></div>
<div id="byline"></div>
</main>
<section>
<h1>Copy Your Words</h1>
<h1>Copy Your <span class="purple">Words</span></h1>
<p>Copy the words you found here for alt-text, editing and archive! (Remember we dont keep anything, so once you close this page, this poem is gone!)</P>
<button id="copy_text">Copy</button>
<button id="copy_text_meta">Copy with meta</button>
<div id="copy_buttons">
<button id="copy_text" class="btn btn-mn">Copy</button>
<button id="copy_text_meta" class="btn btn-mn">Copy with meta</button>
</div>
<div id="poem_list"></div>
</section>
<hr>
<footer>
<p>This site made with <a href="https://jquery.com/">jQuery</a>, PHP and <a href="https://www.barebones.com/products/bbedit/">BBEdit</a> with help from <a href="https://espressoapp.com/">Espresso</a>.</p>
<p><a href="https://code.jacobhaddon.com/jake/smhn">Code</a> by Jacob Haddon - license <a href="https://www.gnu.org/licenses/gpl-3.0.en.html">GPLv3.0</a> - <a href="https://Apokrupha.com/BlackOut">Apokrupha.com/Blackout</a></p>
</footer>
<hr>
<div class="helpbox help">
<button class="helpbtn">Close</button>
</div>
<!--Help Section-->
<div id="help" class="help">
<div class="help btn-hlp-bx">
<button class="btn btn-hlp helpbtn">Close</button>
</div>
<div class="helpwords">
<h1>Help</h1>

View File

@ -13,20 +13,19 @@ Written by Jacob Haddon https://jacobhaddon.com
@font-face {
font-family: "lora";
src: local("Lora"),
url("fonts/Lora/Lora-VariableFont_wght.ttf");
}
@font-face {
font-family: "brygada";
src: local("Brygada1918"),
url("fonts/Brygada_1918/Brygada1918-VariableFont_wght.ttf");
url("fonts/Lora/webfonts/Lora-Regular.woff2") format('woff2'),
url("fonts/Lora/variable/Lora-VariableFont_wght.ttf") format('truetype');
font-style: normal;
font-weight: normal;
}
@font-face {
font-family: "lora";
src: local("Lora"),
url("fonts/Lora/Lora-VariableFont_wght.ttf");
url("fonts/Lora/webfonts/Lora-Italic.woff2") format('woff2'),
url("fonts/Lora/variable/Lora-Italic-VariableFont_wght.ttf")format('truetype');
font-weight: normal;
font-style: italic;
}
body {
@ -46,6 +45,10 @@ a:hover {
text-decoration: underline;
}
.purple {
color: RebeccaPurple;
}
.help {
display: none;
}
@ -53,11 +56,11 @@ a:hover {
/* Styles for the help section of the site */
#help {
background-color: black;
color: white;
position: absolute;
top: 0%;
left: 0%;
background-color: black;
width: 100%;
}
@ -65,26 +68,19 @@ a:hover {
color: white;
}
.helpbox {
position: fixed;
top: 20px;
right: 20px;
z-index: 10;
}
.helpwords {
margin: 40px auto;
max-width: 650px;
}
/* styles for the 'page */
#spina {
max-width: 100%;
margin: 0;
border-style: solid;
padding: 10%;
border-style: solid;
border-width: 1px;
/*background-color: #fdf8e9;*/
}
#byline {
@ -92,15 +88,64 @@ a:hover {
padding: 0 25px 25px 25px;
}
#poem_list {
min-height: 75px;
border: 2px solid RebeccaPurple;
padding: 50px 5% 5%;
}
#copy_buttons {
float: right;
}
.click {
background-color: Plum;
}
/* Styles for the buttons */
/* all buttons have this */
.btn {
-webkit-appearance: none;
appearance: none;
font: 18px lora, Baskerville, TimesNewRoman, Times New Roman, Times, Georgia, serif;
padding: 8px;
border-style: none;
-webkit-appearance: none;
}
.btn-mn {
background-color: RebeccaPurple;
color: #ffffff;
}
.btn-mn:hover {
background-color: black;
color: white;
}
.btn-hlp-bx {
position: fixed;
top: 40px;
right: 10%;
z-index: 10;
float: right;
}
.btn-hlp {
background-color: white;
}
.btn-hlp:hover {
background-color: silver;
}
/* Styles for the blacked-out page */
.clickDone {
background-color: white;
padding: 2px;
color: black;
}
.done {
@ -108,7 +153,3 @@ a:hover {
/*border: 10px solid black;*/
}
.purple {
color: RebeccaPurple;
}