How do I add images dynamically to a book chapter in Drupal 8?

I have build a site that has a number of different data types. Each data type is dated and has various fields including an image for that item (node).

I have constructed code to create a master book and then chapters for each of the data types. This is the basic structure of my overall book.

Master Book

  • Type 1 Book Chapter <—– Want to display a table of images for nodes 1, 2, and 5
    — Data node 1
    — Data node 2
    — Data node 5
  • Type 2 Book Chapter <—– Want to display a table of images for nodes 3, and 3
    — Data node 3
    — Data node 6
  • Type 3 Book Chapter <—– Want to display a table of images for nodes 4, and 7
    — Data node 4
    — Data node 7

When a new data item gets added the node that is generated gets put into the book outline appropriately by type. The data comes in on a regular basis (some hourly, some daily).

I would like the Type chapters to display a table of the thumbnail images for all nodes that are children to that chapter. This process needs to be dynamic as nodes get generated and added to the chapters.

I did this in Drupal 7 using php code in the body field of the chapters with a callback function to generate the table. This is not working in drupal 8.

beginner – Rust Book’s Chapter 8 – Text Interface

I recently finished chapter 8 of Rust’s book, and below is my solution to the third exercise. I’d appreciate pointers on how the code can be improved. Thanks in advance.

use std::collections::HashMap;

//An attempt at Rust book's chapter 8's third exercise:
//https://doc.rust-lang.org/book/ch08-03-hash-maps.html

fn main() {
    println!("The Office - Text Interface.");
    println!();
    println!("Enter a query, type HELP for a list of keyword and their functions, or type EXIT to exit.");
    println!();

    //build hashmap{department: vec(names)} database, insert default values
    let mut company = HashMap::new();
    
    let depts = vec!("SALES", "ENGINEERING", "HR", "SANITATION");

    let sales = vec!("Sally", "Jordan", "Charlie", "Abigail");
    let engineering = vec!("Suzy", "Jay", "Chi", "Amy");
    let hr = vec!("Son", "Jack", "Chia", "Anna");
    let sanitation = vec!("August", "Entangle", "Will", "Jada");
    let tup = (sales, engineering, hr, sanitation);

    let mut g: Vec<_> = Vec::new();
    company = depts.into_iter()
    .map(|x| x.to_string())
    .zip(tup.iter().map(|y| {g = y.iter().map(|q| q.to_string()).collect(); g.clone()}))
    .collect();

    let keywords = ("ADD", "LIST", "UPDATE", "REMOVE", "HELP", "EXIT");

    // loop the input part of the text interface.
    //validate first keyword, send queries to functions.
    loop {
        let mut query = String::new();
        println!("::");

        //check for empty input
        io::stdin().read_line(&mut query).expect("Enter a valid input");
        query = query.trim().to_string();
        // println!("{}", query);
        if query.is_empty() {
            println!("Invalid input. Type HELP for a keyword reference.");
            continue;
        }

        //check for valid first keyword
        let keyword = query.split_whitespace().next().unwrap().to_uppercase();
        if !keywords.contains(&&keyword(..)) {
            println!("Invalid Keyword. Type HELP for a keyword reference.");
            continue;
        }

        //keyword validated. Call the function.
        let mut query = query.split_whitespace().collect::<Vec<_>>();
        match &&keyword(..) {
            &"EXIT" => return,
            &"HELP" => help(),
            &"ADD" => add(&mut query, &mut company),
            &"LIST" => list(&mut query, &mut company),
            &"UPDATE" => update(&mut query, &mut company),
            &"REMOVE" => remove(&mut query, &mut company),
            _ => (),
        }
        // println!("{:?}", company); //debug purposes: print the entire hashmap on each loop to monitor changes.
        continue;
    }
}

fn add(q: &mut Vec<&str>, company: &mut HashMap<String, Vec<String>>) {

    //validate add syntax
    let length = q.len();
    if length < 3 || length > 4 {
        println!("Invalid ADD syntax. Type HELP for a keyword reference.");
        return;
    }

    //add a new department
    if length == 3 {
        match (q(0), q(1), q(2)) {
            ("ADD", "-D", d) => {

                //check if dept exists
                let dept = d.to_uppercase();
                if company.contains_key(&dept) {
                    println!("Department {} already exists.", d);
                    return;
                }

                //add dept
                company.entry(dept).or_insert(Vec::new());
                println!("Created department {}.", d);
                return;

            }

            _ => {
                println!("Invalid syntax.");
                return;
            }
        }
    }

    //add a person to a department
    if length == 4 {
        match (q(0), q(1), q(2), q(3)) {
            ("ADD", name, "TO", d) => {

                //check if dept exists
                let dept = d.to_uppercase();
                if !company.contains_key(&dept) {
                    println!("Department {} does not exist.", d);
                    return;
                }

                //check if name already exists in dept
                if company(&dept).contains(&name.to_owned()) {
                    println!("The name {} already exists in {}.", name, dept);
                    return;
                }
                //add name to vector
                (*company.get_mut(&dept).unwrap()).push(name.to_owned());
                println!("Added {} to {}.", name, d);
            }
            _ => {
                println!("Invalid Syntax");
                return;
            }
        }
    }
}

fn list(q: &mut Vec<&str>, company: &mut HashMap<String, Vec<String>>) {

    //sanitize input
    let length = q.len();
    if length != 2 && length !=4 {
        println!("Invalid number of arguments.");
        return;
    }

    if length == 2 {
        match (q(0), q(1)) {

            //list all depts
            ("LIST", "-D") => {
                let mut depts: Vec<_> = company.keys().collect();
                depts.sort();
                for d in depts {
                    println!("{}", d);
                }
                return;
            }

            //list everyone in all depts, sorted alphabetically
            ("LIST", "-E") => {
                for (dept, mut names) in company.clone() {
                    println!("---{}---", dept);
                    names.sort();
                    for name in names {
                        println!("{}", name);
                    }
                }
            }
            _ => {
                println!("Invalid Syntax.");
                return;
            }
        }
    }

    if length == 4 {
        match (q(0), q(1), q(2), q(3)) {
            ("LIST", "-E", "IN", d) => {

                //check if dept exists
                let dept = d.to_uppercase();
                if !company.contains_key(&dept) {
                    println!("Department {} does not exist.", d);
                    return;
                }

                //list all in department
                println!("---{}---", dept);
                (*company.get_mut(&dept).unwrap()).sort();
                for name in &company(&dept) {
                    println!("{}", name);
                }
            }
            _ => {
                println!("Invalid Syntax.");
                return;
            }
        }
    }
}

fn update(q: &mut Vec<&str>, company: &mut HashMap<String, Vec<String>>) {
    let length = q.len();

    if length != 5 && length != 6 {
        println!("Invalid UPDATE syntax.");
        return;
    }

    if length == 5 {
        match (q(0), q(1), q(2), q(3), q(4)) {

            //update a department
            ("UPDATE", "-D", old_d, "TO", new_d) => {

                //check if dept exists
                let old_dept = old_d.to_uppercase();
                let new_dept = new_d.to_uppercase();
                if !company.contains_key(&old_dept) {
                    println!("Department {} does not exist.", old_d);
                    return;
                }
                if company.contains_key(&new_dept) {
                    println!("Department {} already exists.", new_d);
                    return;
                }

                //rename dept. Technique is to build a new vector with that same name since you
                //cannot change the key of a hash map.
                let temp_dept = company.get(&old_dept).unwrap().clone();
                company.insert(new_dept.to_uppercase(), temp_dept);
                company.remove(&old_dept);
                println!("Changed Department {} to {}.", old_d, new_d);
                return;

            }
            _ => {
                println!("Invalid syntax.");
                return;
            }
        }
    }

    //change a name in a department
    match (q(0), q(1), q(2), q(3), q(4), q(5)) {
        ("UPDATE", old_name, "FROM", d, "TO", new_name) => {

            //check if dept exists
            let dept = d.to_uppercase();
            if !company.contains_key(&dept) {
                println!("Department {} does not exist.", d);
                return;
            }

            //check if old name and new name exist
            if !company(&dept).contains(&old_name.to_owned()) {
                println!("The name {} does not exist in {}.", old_name, dept);
                return;
            }
            if company(&dept).contains(&new_name.to_owned()) {
                println!("The name {} already exists in {}.", new_name, dept);
                return;
            }

            //update the name.
            for (i, name) in company(&dept).clone().iter().enumerate() {
                if name == old_name {
                    (*company.get_mut(&dept).unwrap())(i) = new_name.to_owned();
                    println!("Changed {} in {} to {}.", old_name, dept, new_name);
                    return;
                }
            }
        }
        _ => {
            println!("Invalid Syntax.");
            return;
        }
    }
}

fn remove(q: &mut Vec<&str>, company: &mut HashMap<String, Vec<String>>) {
    let length = q.len();

    if length !=3 && length !=4 {
        println!("Invalid REMOVE syntax.");
        return;
    }

    if length == 3 {
        match (q(0), q(1), q(2)) {
            ("REMOVE", "-D", d) => {

                //check if dept exists
                let dept = d.to_uppercase();
                if !company.contains_key(&dept) {
                    println!("Department {} does not exist.", d);
                    return;
                }

                //remove the department.
                company.remove(&dept);
                println!("Removed department {}.", d);
                return;

            }
            _ => {
                println!("Invalid Syntax.");
                return;
            }
        }
    }

    //remove a person
    match (q(0), q(1), q(2), q(3)) {
        ("REMOVE", name, "FROM", d) => {

            //check if dept exists
            let dept = d.to_uppercase();
            if !company.contains_key(&dept) {
                println!("Department {} does not exist.", d);
                return;
            }

            //check if name exists
            if !company(&dept).contains(&name.to_owned()) {
                println!("The name {} does not exist in {}.", name, dept);
                return;
            }

            //remove the name
            for (i, _name) in company(&dept).clone().iter().enumerate() {
                if _name == name {
                    (*company.get_mut(&dept).unwrap()).remove(i);
                    println!("Removed {} from {}.", name, dept);
                    return;
                }
            }

        }
        _ => {
            println!("Invalid Syntax.");
            return;
        }
    }
}

fn help() {
    println!("The Office - KEYWORD HELP");
    println!();
    println!("Note: All keywords are case-sensitive.");
    println!("Keywords: nLIST - Lists items in the database");
    println!("Usage:    LIST -E - Lists all employees");
    println!("          LIST -E IN (DEPARTMENT) - Lists all employees in specified department.");
    println!("          LIST -D - Lists all departmnets in the company");
    println!();
    println!("ADD -     Adds items to the database.");
    println!("Usage:    ADD (name) TO (department) - Adds the name to the specified department.");
    println!("          ADD -D (department) - Adds the department to the roster.");
    println!();
    println!("REMOVE -  Removes items from the database.");
    println!("          REMOVE -D (department) - Removes the particular department from the database.");
    println!("          REMOVE (name) FROM (department) - Removes the person from the specified department.");
    println!();
    println!("UPDATE -  Changes records in the database.");
    println!("Usage:    UPDATE -D (old name) TO (new name) - Changes a department's name.");
    println!("          UPDATE (old name) FROM (department) TO (new name) - Changes a person's name.");
    println!();
    println!("HELP -    Prints this help screen.");
    println!();
    println!("EXIT -    Exits the program.")
}

Question about the CLRS Linear Programming chapter

Lemma 29.4 mentions an LP, because that is what they need it for, but it is really a statement in linear algebra about the system of equations $Ax=b$ and a linear form $phi(x)=ccdot x$, which in the LP is the objective function.

Lemma 29.4:

If the variables $x_i,iin B$ are basic variables, i.e. if the corresponding columns of $A$ are a maximal set of linearly independent columns, then you can solve for those variables in terms of the rest of the variables $x_i,iin N$ and the polynomials obtained are unique. In addition, if you write $phi(x)=psi(x_i,iin N)$, the polynomial $psi$ is also unique.

(Well, this version of the lemma includes the assertion that one can solve for those variables. This is due to Gaussian elimination.)

Now, for the uniqueness, as they did, you assume that you have two expressions of the basic variables in terms of the non-basic ones

$(x_i)_{iin B}=(b_i)_{iin B}+S(x_j)_{jin N}$ for some matrix $S$ and $(x_i)_{iin B}=(b_i’)_{iin B}+S'(x_j)_{jin N}$.

So the polynomials $(b_i)_{iin B}+S(x_j)_{jin N}$ and $(b_i’)_{iin B}+S'(x_j)_{jin N}$ are the same.

By definition $(b_i)_{iin B}=(b_i’)_{iin B}$ and $S=S’$.

There is no real need to talk about values of the variables, since all the statements are purely algebraic, in the ring of polynomials in the variables $x_i$. So, there is no need for Lemma 29.3. Of course, the equations written have to be thought as equations between polynomials and not as equations between values of functions that are satisfied for all values of the variables. Ignore this paragraph if it causes confusion.

chapter 2 problem B 27: frank jones lebesgue integration on euclidean spaces

prove that $$lambda^{*}(A) = inf Big{sum_{k=1}^{infty} lambda(I_k) Big| A subset bigcup_{k=1}^{infty} I_k Big}$$

first $displaystyle A subset bigcup_{i=1}^{infty} I_k$ hence we have that $displaystyle lambda^{*}(A) leq lambda^{*}(bigcup_{k=1}^{infty} I_k) leq sum_{k=1}^{infty} lambda^{*}(I_k) = sum_{k=1}^{infty} lambda(I_k) $ since this holds for arbitrarily we have that $lambda^{*}(A) leq inf Big{sum_{k=1}^{infty} lambda(I_k) Big| A subset bigcup_{k=1}^{infty} I_k Big}$

now consider set $A = {lambda(G) : A subset G }$ and $B = { sum_{k=1}^{infty} lambda(I_k) Big| A subset bigcup_{k=1}^{infty} I_k Big}$ since we know that every open set can be written as countable union of disjoint rectangles we have that $G = bigcup_{k=1}^{infty}I_{k}$ so we have that $lambda(G) = sum_{i=1}^{infty} lambda(I_k)$ so we have that $A subset B$ and we know that $displaystyle lambda^{*}(A) = sup_{A subset G} lambda(G)$ by using following property

$A subset B implies inf A leq sup B$

we have that $ inf Big{sum_{k=1}^{infty} lambda(I_k) Big| A subset bigcup_{k=1}^{infty} I_k Big} leq lambda^{*}(A) $

so we are done.

Is above proof correct?

definition – Chapter 2, Exercise 7. Rudin Functional Analysis. Clarification of multiplier property.

Can you clarify what is meant by “multiplier property” in the statement of this exercise?

Let $C(T)$ be the set of all continuous complex functions on the unit circle $T$. Suppose $left{ gamma_n right}, (n in mathbb{Z})$ is a complex sequence that associates to each $f in C(T)$ a function $Lambda f in C(T)$ whose fourier coefficients are
$$
(Lambda f){hat{}}(n) = gamma_n hat{f}(n) ;; (n in mathbb{Z}).
$$

Prove that $left{ gamma_n right}$ has this multiplier property if there’s a complex Borel measure $mu$ on $T$ such that
$$
gamma_n = int e^{-intheta} dmu(theta) ;; (n in mathbb{Z})
$$

Is it meant which $gamma_n$ makes the Fourier series exist?

Spivak’s Calculus Chapter 1, Question 19a

I found this post as solution to the question. Here’s a quote for easy reference.

Supposing $y_1$ and $y_2$ are not both $0$, and that there is no number $lambda$ such that $x_1=lambda y_1$ and $x_2=lambda y_2$, then $$begin{array}{tcl}0 &<& (lambda y_1-x_1)^2 + (lambda y_2-x_2)^2 \ &=& lambda^2 (y_1^2+y_2^2)-2lambda(x_1y_1+x_2y_2)+(x_1^2+x_2^2),end{array}$$ and the equation $$lambda^2 (y_1^2+y_2^2)-2lambda(x_1y_1+x_2y_2)+(x_1^2+y_1^{2 *})=0 \$$
has no solution $lambda$. So by problem 18(a) we must have $$Bigg(frac{2(x_1y_1+x_2y_2)}{({y_1}^2+{y_2}^2)}Bigg)^2-frac{4({x_1}^2+{x_2}^{2 *})}{({y_1}^2+{y_2}^2)} < 0,****** \$$ which yields the Schwarz inequality.

Notice the heavily asterisked line. I don’t understand how we derive this. I recognize that this is “completing the square.” Question 18 emphasized that $b^2 – 4c < 0$ means $x^2 + bx + c > 0$. Except, in this problem, it’s not clear why he choose the $b$ the way he did. Where does the 2 come from? In the sense that, isn’t $b = frac{-2(x_1y_1+x_2y_2)}{({y_1}^2+{y_2}^2)}$.

Real Analysis – Spivak's Calculus Chapter 7, Task 19 (a): A Logical Question

The problem is as follows:

Suppose that $ f $ is continuously on $ (0.1) $ and $ f (0) = f (1) $. To let $ n $ be any natural number. Prove that there is a number $ x $ so that $ f (x) = f (x + frac {1} {n}). $

I was wondering if my proof is logically sound, especially the last piece. I tried to apply the logic of the intermediate value theorem, but I was curious to see whether the contradiction actually gave the desired result:

To let $ g $ be a function that $ g (x) = f (x + frac {1} {n}) – f (x) $. We want to show that there is one $ x in (0.1) $ so that $ g (x) = 0 $. We prove by contradiction.

  1. Accept $ forall x in (0,1), g (x) <0. $ Then for $ i = 0, 1, 2, …, n $ we have that $ g ( frac {i} {n}) <0 $. Therefore, $ f (0)> f ( frac {1} {n})> f ( frac {2} {n})> …> f (1), $ which means, that $ f (0) neq f (1) $.
  2. Following a similar logic follows from this $ g (x)> 0 $ can't keep for everyone $ x in (0.1) $.

Therefore it must exist $ a, b in (0.1) $ so that $ a $ and $ b $ have a different sign, i.e. $ g (a) leq 0 leq g (b) $. According to the intermediate value theorem exists $ c $ so that $ g (c) = 0 $and we're done.

Thank you for your help!

Is there an Android audio player that will allow you to jump to the next chapter in a file?

OK, here is what I mean.

I ripped a collection of .flac files from a CD.

I used a MKA tool on Windows to merge them into a large MKA file with chapter markers between each file.

With VLC Player I can jump from mark to mark on my desktop in this one big MKA file as if this file was a CD.

The problem is, for some reason, VLC for Android does not have this functionality.

Also, I can not find an audio player for Android that offers the "Next Chapter" functionality I'm looking for.

I understand that all available audio players have the "Next item in the playlist" button.

But that does not interest me.

Does anyone know an Android audio player that allows you to jump from chapter to chapter within an MKA file?

Many thanks.