• 1 Post
  • 147 Comments
Joined 1 month ago
cake
Cake day: June 23rd, 2026

help-circle





  • Having done a lot of scanning in the past, no matter how gentle you are, the book will be damaged; at least a little bit. Even if you do it manually, by hand, really slowly.

    It’s the unfortunate reality, because books are not designed to be held open and pressed flat onto an unyielding surface. If you don’t press flat, you’ll get curved pages and bad quality (dark) images, which is sometimes ok and fixable by software, but often not. You can get really fancy expensive machines, but they still don’t fully solve the problem.

    I did scanlation editing stuff for a while, and half my job was making the raw page scans look presentable, because the scanners didn’t want to destroy their manga (understandable).

    https://en.wikipedia.org/wiki/Book_scanning#Methods





  • When I was a senior software engineer, I was offered a management position… I said no, because I knew I would hate it and do a terrible job. I actually like programming, and I absolutely hate asking an A.I. to do it for me.

    Actually funny story. Or maybe unfunny. I was doing a web project a while ago, and the host site I was trying out asked me to describe my project. I naïvely did so, thinking it was like a description or something. When I hit next, the site A.I. automatically did my entire project for me. All the code, folder structures, API calls, everything.

    I just sat there feeling bad feelings for a while. I think it actually made me a bit depressed. Took all the joy out of the project and I never touched it again.






  • Sure, I’m typing it out on my phone though so excuse any mistakes:

    Tap for build.sh
    # build.sh
    php build.php
    
    Tap for build.php
    // build.php
    <?php
    
    // Just contains all the directory definitions and utilities in one place
    require once __DIR__ . './bootstrap.php';
    require once __DIR__ . './utils.php';
    
    // Static assets
    ensureDir(DIST_DIR);
    copy_all_files(ASSETS_DIR, DIST_DIR);
    
    $files = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator(PAGES_DIR)
    );
    
    // Build each page
    foreach ($files as $file) {
        if ($file->isDir()) continue;
        $path = $file->getPathname();
    
        // only build .php pages (skip partials)
        if (!str_ends_with($path, '.php')) continue;
    
        $relative = str_replace('pages/', '', str_replace(SRC_DIR . '/', '', $path));
        $output = str_replace('.php', '/index.html', $relative);
    
        echo $relative . "\n";
        if ($relative == 'index.php') {
            $outputPath = DIST_DIR . '/index.html';
        }
        else if (str_ends_with($output, 'index/index.html')) {
            $output = str_replace('index/index.html', 'index.html', $output);
            $outputPath = DIST_DIR . '/' . $output;
        }
        else {
            $outputPath = DIST_DIR . '/' . $output;
        }
    
        ensureDir(dirname($outputPath));
        ob_start();
        include $path;
        $html = ob_get_clean();
    
        echo $outputPath . "\n";
        file_put_contents($outputPath, $html);
    }
    
    echo "Build complete\n";
    
    Tap for utils.php
    // utils.php
    
    function ensureDir($path) {
        if (!is_dir($path)) {
            mkdir($path, 0777, true);
        }
    }
    
    function copy_all_files($source_dir, $target_dir) {
        $dir_obj = opendir($source_dir);
        @mkdir($target_dir);
        while ($file = readdir($dir_obj)) {
            if ($file != "." && $file != "..") {
                if (is_dir($source_dir . "/" . $file)) {
                    copy_all_files($source_dir . "/" . $file, $target_dir . "/" . $file);
                } else {
                    copy($source_dir . "/" . $file, $target_dir . "/" . $file);
                }
            }
        }
        closedir($dir_obj);
    }
    
    Tap for bootstrap.php
    <?php
    define('ROOT_DIR', __DIR__);
        define('DIST_DIR',  ROOT_DIR . '/dist');
        define('SRC_DIR',   ROOT_DIR . '/src');
            define('PAGES_DIR',     SRC_DIR . '/pages');
    // etc
    

    I stripped out all the database stuff because as my site grew I kept expanding on it and I needed a database.

    Mine will also probably be longer than average because I wanted fancy stuff like my source pages being just “about.php” instead of “about/index.php”, but I wanted the output to be “about/index.html” so it got way more complicated than it needed to be. But again most of those lines in the for loop are just me being obsessive compulsive about my own directory structure 😂. I also didn’t count the utilities functions in my original line count because to me that’s equivalent of importing a module; I didn’t write that file, I just copy pasted it from online. You could probably find a simpler build script online.

    Tap for example.php
    <?php
    $pageTitle = 'Example';
    ?>
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <?php include PARTIALS_DIR . '/head.php'; ?>
        <link rel="stylesheet" href="/styles/example.css" />
    </head>
    <body>
        <?php include PARTIALS_DIR . '/header.php'; ?>
        <?php include PARTIALS_DIR . '/noscript.php'; ?>
        <main>
            <h1>example</h1>
        </main>
    
        <?php include PARTIALS_DIR . '/footer.php'; ?>
        <?php include PARTIALS_DIR . '/global-scripts.php'; ?>
    </body>
    </html>