Help for Managing Exams

Topic : Part 1/2

Summary
  • How to group each h_row of aoh_rows by h_row.Title? (DVJS20)
  • How to embed the “area” and “cover” fields into the callout box of Admonitions? (DVJS10:M13 or DVJS20:M13)

Test

Summary
  • dataview: v0.5.46
  • admonition: v7.0.4

Input

Summary

dictionary files

  • Locations: “100_Project/01_dataviewjs/01_by_example/Q27_Admonition/Q27_test_data”

folder: 03_markdown_file_outside

  • filename : dic_19680301
---
Date: 1968-03-01
---
#Project/P03


```ad-abstract
title: Explain Recursion (5)
area: General
cover: ![|150](file:///E:/Q27_test_data_images/Q27_General01.jpg)
For an explaition of recursion, please look up Recursion
```



```ad-abstract
title: Explain Mergesort (3)
area: Sorting
cover: ![|150](file:///E:/Q27_test_data_images/Q27_Sorting01.jpg)
It is 42
```



```ad-abstract
title: Explain Iteration (2)
area: Loop
cover: ![|150](file:///E:/Q27_test_data_images/Q27_Loop01.jpg)
It is the opposite of recursion
```




folder: 04_markdown_file_outside

  • filename : dic_19680401
---
Date: 1968-04-01
---
#Project/P04


```ad-abstract
title: Explain Recursion (50)
area: General
cover: ![|150](file:///E:/Q27_test_data_images/Q27_General01.jpg)
It is Q1.
```



```ad-abstract
title: Explain Mergesort (30)
area: Sorting
cover: ![|150](file:///E:/Q27_test_data_images/Q27_Sorting01.jpg)
It is Q2.
```



```ad-abstract
title: Explain Iteration (20)
area: Loop
cover: ![|150](file:///E:/Q27_test_data_images/Q27_Loop01.jpg)
It is Q3.
```




folder: 12_excluded

  • filename : dic_19681201
---
Date: 1968-12-01
---
#Project/P12




images files

  • Both the DVJS10 and DVJS20 support the following file URLs or https URLs.

A local image outside the Obsidian vault: Absolute File Paths (A file URL starting with file:///)

  • A file URL: “file:///E:/Q27_test_data_images/Q27_General01.jpg”

CASE10_markdown_file_outside: To use the markdown syntax with the file URL which is outside the Obsidian vault

```ad-abstract
title: Explain Recursion (50)
area: General
cover: ![|150](file:///E:/Q27_test_data_images/Q27_General01.jpg)
It is Q1.
```

OR

CASE20_HTML_file_outside: To use the HTML syntax with the file URL which is outside the Obsidian vault

```ad-abstract
title: Explain Recursion (50)
area: General
cover: <img width='150px' src='file:///E:/Q27_test_data_images/Q27_General01.jpg'>
It is Q1.
```

A local image inside the Obsidian vault: Absolute File Paths (A file URL starting with file:///)

  • A file URL: “file:///E:/note_a8/Q27_Admonition/Q27_test_data_images/Q27_General01.jpg”
  • Locations of the Obsidian vault: “file:///E:/note_a8/”

CASE11_markdown_file_inside: To use the markdown syntax with the file URL which is inside the Obsidian vault

```ad-abstract
title: Explain Recursion (50)
area: General
cover: ![|150](file:///E:/note_a8/Q27_Admonition/Q27_test_data_images/Q27_General01.jpg)
It is Q1.
```

OR

CASE21_HTML_file_inside: To use the HTML syntax with the file URL which is inside the Obsidian vault

```ad-abstract
title: Explain Recursion (50)
area: General
cover: <img width='150px' src='file:///E:/note_a8/Q27_Admonition/Q27_test_data_images/Q27_General01.jpg'>
It is Q1.
```

An online image


CASE30_markdown_https_online: To use the markdown syntax with the https URL which is an online image

```ad-abstract
title: Explain Recursion (50)
area: General
cover: ![|150](https://m.media-amazon.com/images/I/41aGGHu7Q-L._SX361_BO1,204,203,200_.jpg)
It is Q1.
```

OR

CASE40_HTML_https_online: To use the HTML syntax with the https URL which is an online image

```ad-abstract
title: Explain Recursion (50)
area: General
cover: <img width='150px' src='https://m.media-amazon.com/images/I/41aGGHu7Q-L._SX361_BO1,204,203,200_.jpg'>
It is Q1.
```

DVJS10_TABLE_key_value_pairs_via_RegExp_and_Obsidian_API

Summary

Main DVJS

Code Name Data type Group By Purposes Remark
DVJS10
_TABLE
_key_value_pairs
_via_RegExp
_and_Obsidian_API
callout:
a multi-line string

(A variable)
aoh_rows:
an array of JavaScript Objects
no 1.To get key-value pairs via RegExp and Obsidian API
2.To filter by h_row.Area
3.To filter by h_row.Title
4.To sort by h_row.Title in ascending order
5.To display the result as a table
1.To require the plugin admonition

Notes

Summary

Q1: What does the cover field in the callout box of Admonitions mean?

Summary_Q1
Original Example: Q1 (To be explained)

The local image lke Q27_General01.jpg is outside the Obsidian vault.
The following markdown sytax in cover field will be rendered as the following HTML systax in the A1_11.
Tips:
CASE10_markdown_file_outside: To use the markdown syntax with the file URL which is outside the Obsidian vault

---
Date: 1968-03-01
---
#Project/P03
```ad-abstract
title: Explain Recursion (5)
area: General
cover: ![|150](file:///E:/Q27_test_data_images/Q27_General01.jpg)
For an explaition of recursion, please look up Recursion
```



A1_11: a local image outside the Obsidian vault

Another Example: A1_11

The local image lke Q27_General01.jpg is outside the Obsidian vault.
The following HTML systax in cover field can be simplified as the above markdown systax in the Q1.
Tips:
CASE20_HTML_file_outside: To use the HTML syntax with the file URL which is outside the Obsidian vault

---
Date: 1968-03-01
---
#Project/P03
```ad-abstract
title: Explain Recursion (5)
area: General
cover: <img width='150px' src='file:///E:/Q27_test_data_images/Q27_General01.jpg'>
For an explaition of recursion, please look up Recursion
```



A1_12: a local image inside the Obsidian vault

Another Example: A1_12

The local image lke Q27_General01.jpg is inside the Obsidian vault which locates in the path like ''file:///E:/note_a8/".
Tips:
CASE11_markdown_file_inside: To use the markdown syntax with the file URL which is inside the Obsidian vault

---
Date: 1968-03-01
---
#Project/P03
```ad-abstract
title: Explain Recursion (5)
area: General
cover: ![|150](file:///E:/note_a8/Q27_Admonition/Q27_test_data_images/Q27_General01.jpg)
For an explaition of recursion, please look up Recursion
```



A1_13: an online image

Another Example: A1_13

The following image lke 41aGGHu7Q-L._SX361_BO1,204,203,200_.jpg is an online image.
Tips:
CASE30_markdown_https_online: To use the markdown syntax with the https URL which is an online image

---
Date: 1968-03-01
---
#Project/P03
```ad-abstract
title: Explain Recursion (5)
area: General
cover: ![|150](https://m.media-amazon.com/images/I/41aGGHu7Q-L._SX361_BO1,204,203,200_.jpg)
For an explaition of recursion, please look up Recursion
```



Q2: How not to filter by h_row.Area and /Iteration|Mergesort|Recursion/.test(h_row.Title)? (M41)

Summary_Q2
Original Example: Q2 (To be modified)
```dataviewjs
// M41. filter and sort aoh_rows:
// WHERE_CASE_10:To gather a `h_row` where `h_row.Area` is truthy
// (comments)WHERE_CASE_11:To gather a `h_row` which contains "Explain" 
// WHERE_CASE_12:To gather a `h_row` which matches the regular pattern 
//               like /Iteration|Mergesort|Recursion/
// Tips: See the output of the M39 and modify the M41 as needs.
// #####################################################################
aoh_rows = aoh_rows
    .where((h_row) => h_row.Area)
    // .where((h_row) => dv.func.contains(h_row.Title, "Explain"))
    .where((h_row) =>
        /Iteration|Mergesort|Recursion/.test(h_row.Title)
    )
    .sort((h_row) => h_row.Title, "asc");


```

A2_21:

Another Example: A2_21
```dataviewjs
// M41. filter and sort aoh_rows:
// WHERE_CASE_10:To gather a `h_row` where `h_row.Area` is truthy
// (comments)WHERE_CASE_11:To gather a `h_row` which contains "Explain" 
// WHERE_CASE_12:To gather a `h_row` which matches the regular pattern 
//               like /Iteration|Mergesort|Recursion/
// Tips: See the output of the M39 and modify the M41 as needs.
// #####################################################################
aoh_rows = aoh_rows
    // .where((h_row) => h_row.Area)
    // .where((h_row) => dv.func.contains(h_row.Title, "Explain"))
    // .where((h_row) =>
    //     /Iteration|Mergesort|Recursion/.test(h_row.Title)
    // )
    .sort((h_row) => h_row.Title, "asc");


```

Q3: What does the following code mean? (M41:WHERE_CASE_12)

Summary_Q3
Original Example: Q3 (To be explained)
```dataviewjs
// M41. filter and sort aoh_rows:
// WHERE_CASE_10:To gather a `h_row` where `h_row.Area` is truthy
// (comments)WHERE_CASE_11:To gather a `h_row` which contains "Explain" 
// WHERE_CASE_12:To gather a `h_row` which matches the regular pattern 
//               like /Iteration|Mergesort|Recursion/
// Tips: See the output of the M39 and modify the M41 as needs.
// #####################################################################
aoh_rows = aoh_rows
    .where((h_row) => h_row.Area)
    // .where((h_row) => dv.func.contains(h_row.Title, "Explain"))
    .where((h_row) =>
        /Iteration|Mergesort|Recursion/.test(h_row.Title)
    )
    .sort((h_row) => h_row.Title, "asc");


```

A3_31:

Another Example: A3_31
```dataviewjs
// M41. filter and sort aoh_rows:
// WHERE_CASE_10:To gather a `h_row` where `h_row.Area` is truthy
// (comments)WHERE_CASE_11:To gather a `h_row` which contains "Explain" 
// WHERE_CASE_12:To gather a `h_row` which matches the regular pattern 
//               like /Iteration|Mergesort|Recursion/
// Tips: See the output of the M39 and modify the M41 as needs.
// #####################################################################
aoh_rows = aoh_rows
    .where((h_row) => h_row.Area)
    // .where((h_row) => dv.func.contains(h_row.Title, "Explain"))
    .where(
        (h_row) =>
            dv.func.contains(h_row.Title, "Iteration") ||
            dv.func.contains(h_row.Title, "Mergesort") ||
            dv.func.contains(h_row.Title, "Recursion")
    )
    .sort((h_row) => h_row.Title, "asc");



```

Code DVJS10_TABLE_key_value_pairs_via_RegExp_and_Obsidian_API

Summary_code
title: DVJS10_TABLE_key_value_pairs_via_RegExp_and_Obsidian_API => 0.To require the plugin admonition 1.To get key-value pairs via RegExp and Obsidian API 2.To filter by h_row.Area 3.To filter by h_row.Title 4.To sort by h_row.Title in ascending order 5.To display the result as a table
collapse: open
icon: 
color: 
```dataviewjs
// M11. define pages: gather all relevant pages
// #####################################################################
const pages = dv.pages(
    '"100_Project/01_dataviewjs/01_by_example/Q27_Admonition/Q27_test_data"'
);


// M13. define regex: find the contents of a specifically formatted callout
// REGEX_CALLOUT_BOX_OF_ADMONITION
// input:
// 
// ```ad-abstract
// title: Explain Recursion (5)
// area: General
// cover: ![|150](file:///E:/Q27_test_data_images/Q27_General01.jpg)
// For an explaition of recursion, please look up Recursion
// ```
// 
// output:
// Title="Explain Recursion"
// Points="5"
// Area="General"
// Cover="![|150](file:///E:/Q27_test_data_images/Q27_General01.jpg)"
// Content="For an explaition of recursion, please look up Recursion\n"
//
// OS       Abbreviation  Escape sequence
// Windows : CR+LF         \r\n
// UNIX    : LF            \n
// MAC     : CR            \r
//
// 1.Following Unix, Obsidian under different operating systems uses 
//   LF alone as a line terminator in a markdown file.
// 2.In other words, a markdown file created in Obsidian under different 
//   operating systems uses LF alone as a line terminator.
// 3.Howerver, a read-only markdown file with CR+LF(or CR) as a line 
//   terminator still keeps its original newline. Obsidian cannot transform 
// a newline into LF because the file does not have write permission.
// 4.Therefore, if there is no read-only markdown file,
//  uses LF alone like `let regex_Newline = /(?=\n)/g;`. 
// Otherwise, uses `let regex_Newline = /(?=\r?\n|\r)/g;`
// 
// non-greedy y*?
// non-greedy y+?
// Named Capture Group(?<Name>y)
// #####################################################################
// const regex = /```ad-(\w+)\r?\ntitle:(.+?)\((\d*?)\)\r?\n(.+?)```/
const regex =
    /```ad-(\w+)\r?\ntitle:\s*(?<Title>.+?)\s*\((?<Points>\d*?)\)\r?\narea:\s*(?<Area>.+?)\s*\r?\ncover:\s*(?<Cover>.+?)\s*\r?\n(?<Content>.+?)```/;



// M21. define aoh_rows : a JavaScript array
// #####################################################################
let aoh_rows = [];


// M23. update aoh_rows : 
// transform a JavaScript array into a Dataview data array by using dv.array
// #####################################################################
aoh_rows = dv.array(aoh_rows);


// M31. gather the formatted data :
// #####################################################################
for (const page of pages) {
    
    // M31.FR10 define file:
    // #####################################################################
    const file = app.vault.getAbstractFileByPath(page.file.path);


    // M31.FR12 define contents: Read the file contents
    // #####################################################################
    const contents = await app.vault.read(file);


    // M31.FR14 Extract the summary via regex :
    // g modifier: global. All matches (don't return after first match)
    // s modifier: single line. Dot matches newline characters
    // #####################################################################
    for (const callout of contents.match(new RegExp(regex, "sg")) || []) {
        

        // M31.FR14.FR11 define match :
        // s modifier: single line. Dot matches newline characters
        // ##################################################################### 
        const match = callout.match(new RegExp(regex, "s"));


        // M31.FR14.FR13 push the key-value pairs into the array aoh_rows:
        // #####################################################################
        // aoh_rows.push([match[2], match[3],match[4],match[5], page.file.link]);   
        // aoh_rows["values"].push({
        //     Title: match[2],
        //     Points: match[3],
        //     Area: match[4],
        //     Content: match[5],
        //     Link: page.file.link,
        // }); 
        aoh_rows["values"].push({
            Title: match.groups?.Title,
            Points: match.groups?.Points,
            Area: match.groups?.Area,
            Cover: match.groups?.Cover,           
            Content: match.groups?.Content,
            Name_Of_File: page.file.name,
            Path_Of_File: page.file.path,          
            Link_Of_File: page.file.link,
        });
        
    }
}


// M39. dedbug output aoh_rows:
// #####################################################################
// dv.span("The following is the content of the `aoh_rows` from the DVJS10.<br>");
// aoh_rows.forEach((h_row) => {
//     if (h_row.Name_Of_File === "dic_19680301") {
//         dv.span(JSON.stringify(h_row, null, 2), "\n");
//     }
// });


// The following is the content of the aoh_rows from the DVJS10.
// [
//     {
//         Title: "Explain Recursion",
//         Points: "5",
//         Area: "General",
//         Cover: "![|150](file:///E:/Q27_test_data_images/Q27_General01.jpg)", //=>It is rendered as a image.
//         Content: "For an explaition of recursion, please look up Recursion\n",
//         Name_Of_File: "dic_19680301",
//         Path_Of_File:
//             "100_Project/01_dataviewjs/01_by_example/Q27_Admonition/Q27_test_data/03/dic_19680301.md",
//         Link_Of_File: {
//             path: "100_Project/01_dataviewjs/01_by_example/Q27_Admonition/Q27_test_data/03/dic_19680301.md",
//             embed: false,
//             type: "file",
//         },
//     },
//     {
//         Title: "Explain Mergesort",
//         Points: "3",
//         Area: "Sorting",
//         Cover: "![|150](file:///E:/Q27_test_data_images/Q27_Sorting01.jpg)", //=>It is rendered as a image.
//         Content: "It is 42\n",
//         Name_Of_File: "dic_19680301",
//         Path_Of_File:
//             "100_Project/01_dataviewjs/01_by_example/Q27_Admonition/Q27_test_data/03/dic_19680301.md",
//         Link_Of_File: {
//             path: "100_Project/01_dataviewjs/01_by_example/Q27_Admonition/Q27_test_data/03/dic_19680301.md",
//             embed: false,
//             type: "file",
//         },
//     },
//     {
//         Title: "Explain Iteration",
//         Points: "2",
//         Area: "Loop",
//         Cover: "![|150](file:///E:/Q27_test_data_images/Q27_Loop01.jpg)", //=>It is rendered as a image.
//         Content: "It is the opposite of recursion\n",
//         Name_Of_File: "dic_19680301",
//         Path_Of_File:
//             "100_Project/01_dataviewjs/01_by_example/Q27_Admonition/Q27_test_data/03/dic_19680301.md",
//         Link_Of_File: {
//             path: "100_Project/01_dataviewjs/01_by_example/Q27_Admonition/Q27_test_data/03/dic_19680301.md",
//             embed: false,
//             type: "file",
//         },
//     },
// ];


// M41. filter and sort aoh_rows:
// WHERE_CASE_10:To gather a `h_row` where `h_row.Area` is truthy
// (comments)WHERE_CASE_11:To gather a `h_row` which contains "Explain" 
// WHERE_CASE_12:To gather a `h_row` which matches the regular pattern 
//               like /Iteration|Mergesort|Recursion/
// Tips: See the output of the M39 and modify the M41 as needs.
// #####################################################################
aoh_rows = aoh_rows
    .where((h_row) => h_row.Area)
    // .where((h_row) => dv.func.contains(h_row.Title, "Explain"))
    .where((h_row) =>
        /Iteration|Mergesort|Recursion/.test(h_row.Title)
    )
    .sort((h_row) => h_row.Title, "asc");


// M51. Output aoh_rows as a table: 
// #####################################################################
//dv.span(aoh_rows);
dv.table(
    ["Area", "Cover", "Question", "Points", "Content", "Exame"],
    aoh_rows.map((h_row) => [
        h_row.Area,
        h_row.Cover,  
        h_row.Title,
        h_row.Points,
        h_row.Content,
        h_row.Link_Of_File,
    ])
);


```

Screenshots(DVJS10)


1 Like