├── .github
└── workflows
│ └── nodejs.yml
├── .gitignore
├── LICENSE.md
├── config.toml
├── main.ts
├── package.json
├── pnpm-lock.yaml
├── readme.md
└── tsconfig.json
/.github/workflows/nodejs.yml:
--------------------------------------------------------------------------------
1 | name: Publish Book Daily
2 |
3 | on:
4 | push:
5 | branches: [main]
6 | schedule:
7 | - cron: "0 0 1 * *"
8 | jobs:
9 | build:
10 | runs-on: ubuntu-latest
11 |
12 | strategy:
13 | matrix:
14 | node-version: [20.x]
15 | steps:
16 | - name: Get current date
17 | id: date
18 | run: echo "::set-output name=date::$(date +'%Y-%m-%d')"
19 | - uses: actions/checkout@v2
20 | - name: Use Node.js ${{ matrix.node-version }}
21 | uses: actions/setup-node@v2
22 | with:
23 | node-version: ${{ matrix.node-version }}
24 | - run: npm install -g yarn
25 | - run: yarn
26 | - run: yarn playwright install --with-deps
27 | - run: yarn start
28 |
29 | - uses: "marvinpinto/action-automatic-releases@latest"
30 | with:
31 | repo_token: "${{ secrets.GITHUB_TOKEN }}"
32 | automatic_release_tag: release-${{ steps.date.outputs.date }}
33 | prerelease: false
34 | title: Release ${{ steps.date.outputs.date }}
35 | files: |
36 | *.pdf
37 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | *.pdf
3 | .vscode
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Shirshak
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/config.toml:
--------------------------------------------------------------------------------
1 | [Books.The_Rust_Programming_Language]
2 | print_url="https://doc.rust-lang.org/book/print.html"
3 | file_name="the_rust_programming_language.pdf"
4 |
5 | [Books.High_Assurance_Rust]
6 | print_url="https://highassurance.rs/print.html"
7 | file_name="high_assurance_rust.pdf"
8 |
9 | [Books.Nomicon]
10 | print_url="https://doc.rust-lang.org/nomicon/print.html"
11 | file_name="nomicon.pdf"
12 |
13 | [Books.Rust_Cookbook]
14 | print_url="https://rust-lang-nursery.github.io/rust-cookbook/print.html"
15 | file_name="cookbook.pdf"
16 |
17 | [Books.RustWasm]
18 | print_url="https://rustwasm.github.io/docs/book/print.html"
19 | file_name="rust_wasm.pdf"
20 |
21 | [Books.EasyRust]
22 | print_url="https://dhghomon.github.io/easy_rust/print.html"
23 | file_name="easy_rust.pdf"
24 |
25 | [Books.EmbeddedRust]
26 | print_url="https://docs.rust-embedded.org/book/print.html"
27 | file_name="embedded_rust_book.pdf"
28 |
29 | [Books.RustReference]
30 | print_url="https://doc.rust-lang.org/reference/print.html"
31 | file_name="rust_reference.pdf"
32 |
33 | [Books.ClI]
34 | print_url="https://rust-cli.github.io/book/print.html"
35 | file_name="rust_cli.pdf"
36 |
37 | [Books.RustByExample]
38 | print_url="https://doc.rust-lang.org/rust-by-example/print.html"
39 | file_name="rust_by_example.pdf"
40 |
41 | [Books.RustFuzzBook]
42 | print_url="https://rust-fuzz.github.io/book/print.html"
43 | file_name="rust_fuzz.pdf"
44 |
45 | [Books.RustPerformanceBook]
46 | print_url="https://nnethercote.github.io/perf-book/print.html"
47 | file_name="rust_performance.pdf"
48 |
49 | [Books.RustDesignPatterns]
50 | print_url="https://rust-unofficial.github.io/patterns/print.html"
51 | file_name="rust_design_patterns.pdf"
52 |
53 | [Books.LearnWithLinkedList]
54 | print_url="https://rust-unofficial.github.io/too-many-lists/print.html"
55 | file_name="rust_linked_list.pdf"
56 |
57 |
58 | [Books.RustPractiseQuestions]
59 | print_url="https://rust-unofficial.github.io/rust-practise-questions/print.html"
60 | file_name="rust_practise_questions.pdf"
61 |
62 | [Books.The_Rust_Discovery-microbit]
63 | print_url="https://docs.rust-embedded.org/discovery/microbit/print.html"
64 | file_name="microbit_beginner_rust.pdf"
65 |
66 | [Books.The_Rust_DiscoverySTM]
67 | print_url="https://docs.rust-embedded.org/discovery/f3discovery/print.html"
68 | file_name="stm32f3discovery_beginner_rust.pdf"
--------------------------------------------------------------------------------
/main.ts:
--------------------------------------------------------------------------------
1 | import { Browser, chromium } from "playwright"
2 | import path from "path"
3 | import process from "process"
4 | import toml from "toml"
5 | import fs from "fs"
6 | import pLimit from 'p-limit'
7 | import { setTimeout as delay } from "node:timers/promises"
8 |
9 | declare const document: any
10 |
11 | let config = toml.parse(fs.readFileSync("./config.toml").toString())
12 |
13 |
14 | async function main() {
15 | console.log("Starting", { debugFirstPageOnly: process.env.DEBUG_ONLY_FRIST === "true" })
16 | let browser = await chromium.launch({ headless: true })
17 |
18 | // concurrency of 5
19 | let limit = pLimit(10)
20 | let proms = []
21 |
22 | for (let book_key in config.Books) {
23 | for (let mode of ["dark", "light"] as const) {
24 | proms.push(limit((...args) => fetchBook(...args), book_key, browser, mode))
25 | }
26 |
27 | if (process.env.DEBUG_ONLY_FRIST === "true") {
28 | break
29 | }
30 | }
31 |
32 | await Promise.all(proms)
33 | console.log("Completed")
34 | await browser.close()
35 | process.exit(0)
36 | }
37 |
38 | async function fetchBook(book_key: string, browser: Browser, mode: "dark" | "light") {
39 | let context = await browser.newContext({ colorScheme: mode })
40 | let page = await context.newPage()
41 | let book = config.Books[book_key]
42 |
43 | console.log("Download from", book_key)
44 |
45 | await page.goto(book.print_url)
46 | await page.evaluate(() => {
47 | // workaround for working with tsx
48 | window.__name = () => { }
49 | let head = document.querySelector("head")
50 | let link = document.createElement("link")
51 | link.href = "https://fonts.googleapis.com/css2?family=Nunito:wght@200;300;900&display=swap"
52 | link.rel = "stylesheet"
53 | head.appendChild(link)
54 |
55 | let link2 = document.createElement("link2")
56 | link2.href = " https://fonts.googleapis.com/css2?family=Fira+Code:wght@300;400;500;600;700&display=swap"
57 | link2.rel = "stylesheet"
58 | head.appendChild(link2)
59 |
60 | var styles = `
61 | html {
62 | font-family: Nunito
63 | }
64 |
65 | body{
66 | margin: 40px 25px 40ox 25px !important;
67 | }
68 |
69 | pre, code {
70 | font-family: 'Fira Code', monospace;
71 | }
72 |
73 | .fa.fa-copy clip-button {
74 | display:none
75 | }
76 |
77 | h1 {
78 | page-break-before: always;
79 | }
80 | `
81 | var styleSheet = document.createElement("style")
82 | styleSheet.type = "text/css"
83 | styleSheet.innerText = styles
84 | document.head.appendChild(styleSheet)
85 | })
86 |
87 | // Add table of contents
88 | await page.evaluate(() => {
89 | // Create the table of contents container
90 | const toc = document.createElement('div')
91 | toc.id = 'table-of-contents'
92 | toc.innerHTML = '
Table of Contents
'
93 | toc.style.margin = '40px'
94 | // Find all headings
95 | const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6')
96 | const tocList = document.createElement('ul')
97 |
98 | // Calculate page height (assuming A4 page size)
99 | const pageHeight = 1122 // A4 height in pixels at 96 DPI
100 |
101 | headings.forEach((heading: any, index: any) => {
102 | const listItem = document.createElement('li')
103 | const link = document.createElement('a')
104 |
105 | // Set the link text and href
106 | link.textContent = heading.textContent
107 | link.href = `#heading-${index}`
108 |
109 | // Add a class based on the heading level
110 | listItem.className = `toc-${heading.tagName.toLowerCase()}`
111 |
112 | // Create a span for the dotted line
113 | const dots = document.createElement('span')
114 | dots.className = 'dots'
115 |
116 | // Append elements
117 | listItem.appendChild(link)
118 | listItem.appendChild(dots)
119 | tocList.appendChild(listItem)
120 |
121 | // Add an id to the heading
122 | heading.id = `heading-${index}`
123 | })
124 |
125 | toc.appendChild(tocList)
126 |
127 | // Insert the table of contents at the beginning of the body
128 | document.body.insertBefore(toc, document.body.firstChild)
129 | })
130 |
131 | if (book.file_name.includes("high_assurance_rust")) {
132 | await page.click("#sidebar-toggle")
133 | }
134 |
135 |
136 | if (process.env.DEBUG_ONLY_FRIST === "true") {
137 | console.log("Waiting for 5 seconds")
138 | await delay(5 * 1000)
139 | } else {
140 | console.log("Waiting for 20 seconds")
141 | await delay(20 * 1000)
142 | }
143 |
144 | let dest = path.resolve(book.file_name.replace(".pdf", `_${mode}.pdf`))
145 | await page.pdf({
146 | path: dest,
147 | format: "A4",
148 | printBackground: true,
149 | margin: {
150 | top: 0,
151 | bottom: 0,
152 | left: 0,
153 | right: 0,
154 | },
155 | displayHeaderFooter: true,
156 | headerTemplate: `
157 |
158 | `,
159 | })
160 |
161 | console.log(`Successfully printed? ${dest}`)
162 | }
163 |
164 | main().catch((e) => {
165 | console.log("Error on main", e)
166 | process.exit(0)
167 | })
168 |
169 | export { }
170 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rust-books",
3 | "type": "module",
4 | "version": "1.0.0",
5 | "main": "main.ts",
6 | "license": "MIT",
7 | "scripts": {
8 | "start": "tsx main.ts"
9 | },
10 | "dependencies": {
11 | "meow": "^13.2.0",
12 | "p-limit": "^6.1.0",
13 | "playwright": "1.47.0",
14 | "toml": "^3.0.0",
15 | "tsx": "^4.19.0"
16 | },
17 | "devDependencies": {
18 | "@types/node": "^22.5.4"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '9.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
7 | importers:
8 |
9 | .:
10 | dependencies:
11 | meow:
12 | specifier: ^13.2.0
13 | version: 13.2.0
14 | p-limit:
15 | specifier: ^6.1.0
16 | version: 6.1.0
17 | playwright:
18 | specifier: 1.47.0
19 | version: 1.47.0
20 | toml:
21 | specifier: ^3.0.0
22 | version: 3.0.0
23 | tsx:
24 | specifier: ^4.19.0
25 | version: 4.19.1
26 | devDependencies:
27 | '@types/node':
28 | specifier: ^22.5.4
29 | version: 22.7.6
30 |
31 | packages:
32 |
33 | '@esbuild/aix-ppc64@0.23.1':
34 | resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==}
35 | engines: {node: '>=18'}
36 | cpu: [ppc64]
37 | os: [aix]
38 |
39 | '@esbuild/android-arm64@0.23.1':
40 | resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==}
41 | engines: {node: '>=18'}
42 | cpu: [arm64]
43 | os: [android]
44 |
45 | '@esbuild/android-arm@0.23.1':
46 | resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==}
47 | engines: {node: '>=18'}
48 | cpu: [arm]
49 | os: [android]
50 |
51 | '@esbuild/android-x64@0.23.1':
52 | resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==}
53 | engines: {node: '>=18'}
54 | cpu: [x64]
55 | os: [android]
56 |
57 | '@esbuild/darwin-arm64@0.23.1':
58 | resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==}
59 | engines: {node: '>=18'}
60 | cpu: [arm64]
61 | os: [darwin]
62 |
63 | '@esbuild/darwin-x64@0.23.1':
64 | resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==}
65 | engines: {node: '>=18'}
66 | cpu: [x64]
67 | os: [darwin]
68 |
69 | '@esbuild/freebsd-arm64@0.23.1':
70 | resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==}
71 | engines: {node: '>=18'}
72 | cpu: [arm64]
73 | os: [freebsd]
74 |
75 | '@esbuild/freebsd-x64@0.23.1':
76 | resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==}
77 | engines: {node: '>=18'}
78 | cpu: [x64]
79 | os: [freebsd]
80 |
81 | '@esbuild/linux-arm64@0.23.1':
82 | resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==}
83 | engines: {node: '>=18'}
84 | cpu: [arm64]
85 | os: [linux]
86 |
87 | '@esbuild/linux-arm@0.23.1':
88 | resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==}
89 | engines: {node: '>=18'}
90 | cpu: [arm]
91 | os: [linux]
92 |
93 | '@esbuild/linux-ia32@0.23.1':
94 | resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==}
95 | engines: {node: '>=18'}
96 | cpu: [ia32]
97 | os: [linux]
98 |
99 | '@esbuild/linux-loong64@0.23.1':
100 | resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==}
101 | engines: {node: '>=18'}
102 | cpu: [loong64]
103 | os: [linux]
104 |
105 | '@esbuild/linux-mips64el@0.23.1':
106 | resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==}
107 | engines: {node: '>=18'}
108 | cpu: [mips64el]
109 | os: [linux]
110 |
111 | '@esbuild/linux-ppc64@0.23.1':
112 | resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==}
113 | engines: {node: '>=18'}
114 | cpu: [ppc64]
115 | os: [linux]
116 |
117 | '@esbuild/linux-riscv64@0.23.1':
118 | resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==}
119 | engines: {node: '>=18'}
120 | cpu: [riscv64]
121 | os: [linux]
122 |
123 | '@esbuild/linux-s390x@0.23.1':
124 | resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==}
125 | engines: {node: '>=18'}
126 | cpu: [s390x]
127 | os: [linux]
128 |
129 | '@esbuild/linux-x64@0.23.1':
130 | resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==}
131 | engines: {node: '>=18'}
132 | cpu: [x64]
133 | os: [linux]
134 |
135 | '@esbuild/netbsd-x64@0.23.1':
136 | resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==}
137 | engines: {node: '>=18'}
138 | cpu: [x64]
139 | os: [netbsd]
140 |
141 | '@esbuild/openbsd-arm64@0.23.1':
142 | resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==}
143 | engines: {node: '>=18'}
144 | cpu: [arm64]
145 | os: [openbsd]
146 |
147 | '@esbuild/openbsd-x64@0.23.1':
148 | resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==}
149 | engines: {node: '>=18'}
150 | cpu: [x64]
151 | os: [openbsd]
152 |
153 | '@esbuild/sunos-x64@0.23.1':
154 | resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==}
155 | engines: {node: '>=18'}
156 | cpu: [x64]
157 | os: [sunos]
158 |
159 | '@esbuild/win32-arm64@0.23.1':
160 | resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==}
161 | engines: {node: '>=18'}
162 | cpu: [arm64]
163 | os: [win32]
164 |
165 | '@esbuild/win32-ia32@0.23.1':
166 | resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==}
167 | engines: {node: '>=18'}
168 | cpu: [ia32]
169 | os: [win32]
170 |
171 | '@esbuild/win32-x64@0.23.1':
172 | resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==}
173 | engines: {node: '>=18'}
174 | cpu: [x64]
175 | os: [win32]
176 |
177 | '@types/node@22.7.6':
178 | resolution: {integrity: sha512-/d7Rnj0/ExXDMcioS78/kf1lMzYk4BZV8MZGTBKzTGZ6/406ukkbYlIsZmMPhcR5KlkunDHQLrtAVmSq7r+mSw==}
179 |
180 | esbuild@0.23.1:
181 | resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==}
182 | engines: {node: '>=18'}
183 | hasBin: true
184 |
185 | fsevents@2.3.2:
186 | resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
187 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
188 | os: [darwin]
189 |
190 | fsevents@2.3.3:
191 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
192 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
193 | os: [darwin]
194 |
195 | get-tsconfig@4.8.1:
196 | resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==}
197 |
198 | meow@13.2.0:
199 | resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==}
200 | engines: {node: '>=18'}
201 |
202 | p-limit@6.1.0:
203 | resolution: {integrity: sha512-H0jc0q1vOzlEk0TqAKXKZxdl7kX3OFUzCnNVUnq5Pc3DGo0kpeaMuPqxQn235HibwBEb0/pm9dgKTjXy66fBkg==}
204 | engines: {node: '>=18'}
205 |
206 | playwright-core@1.47.0:
207 | resolution: {integrity: sha512-1DyHT8OqkcfCkYUD9zzUTfg7EfTd+6a8MkD/NWOvjo0u/SCNd5YmY/lJwFvUZOxJbWNds+ei7ic2+R/cRz/PDg==}
208 | engines: {node: '>=18'}
209 | hasBin: true
210 |
211 | playwright@1.47.0:
212 | resolution: {integrity: sha512-jOWiRq2pdNAX/mwLiwFYnPHpEZ4rM+fRSQpRHwEwZlP2PUANvL3+aJOF/bvISMhFD30rqMxUB4RJx9aQbfh4Ww==}
213 | engines: {node: '>=18'}
214 | hasBin: true
215 |
216 | resolve-pkg-maps@1.0.0:
217 | resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
218 |
219 | toml@3.0.0:
220 | resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==}
221 |
222 | tsx@4.19.1:
223 | resolution: {integrity: sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA==}
224 | engines: {node: '>=18.0.0'}
225 | hasBin: true
226 |
227 | undici-types@6.19.8:
228 | resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==}
229 |
230 | yocto-queue@1.1.1:
231 | resolution: {integrity: sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==}
232 | engines: {node: '>=12.20'}
233 |
234 | snapshots:
235 |
236 | '@esbuild/aix-ppc64@0.23.1':
237 | optional: true
238 |
239 | '@esbuild/android-arm64@0.23.1':
240 | optional: true
241 |
242 | '@esbuild/android-arm@0.23.1':
243 | optional: true
244 |
245 | '@esbuild/android-x64@0.23.1':
246 | optional: true
247 |
248 | '@esbuild/darwin-arm64@0.23.1':
249 | optional: true
250 |
251 | '@esbuild/darwin-x64@0.23.1':
252 | optional: true
253 |
254 | '@esbuild/freebsd-arm64@0.23.1':
255 | optional: true
256 |
257 | '@esbuild/freebsd-x64@0.23.1':
258 | optional: true
259 |
260 | '@esbuild/linux-arm64@0.23.1':
261 | optional: true
262 |
263 | '@esbuild/linux-arm@0.23.1':
264 | optional: true
265 |
266 | '@esbuild/linux-ia32@0.23.1':
267 | optional: true
268 |
269 | '@esbuild/linux-loong64@0.23.1':
270 | optional: true
271 |
272 | '@esbuild/linux-mips64el@0.23.1':
273 | optional: true
274 |
275 | '@esbuild/linux-ppc64@0.23.1':
276 | optional: true
277 |
278 | '@esbuild/linux-riscv64@0.23.1':
279 | optional: true
280 |
281 | '@esbuild/linux-s390x@0.23.1':
282 | optional: true
283 |
284 | '@esbuild/linux-x64@0.23.1':
285 | optional: true
286 |
287 | '@esbuild/netbsd-x64@0.23.1':
288 | optional: true
289 |
290 | '@esbuild/openbsd-arm64@0.23.1':
291 | optional: true
292 |
293 | '@esbuild/openbsd-x64@0.23.1':
294 | optional: true
295 |
296 | '@esbuild/sunos-x64@0.23.1':
297 | optional: true
298 |
299 | '@esbuild/win32-arm64@0.23.1':
300 | optional: true
301 |
302 | '@esbuild/win32-ia32@0.23.1':
303 | optional: true
304 |
305 | '@esbuild/win32-x64@0.23.1':
306 | optional: true
307 |
308 | '@types/node@22.7.6':
309 | dependencies:
310 | undici-types: 6.19.8
311 |
312 | esbuild@0.23.1:
313 | optionalDependencies:
314 | '@esbuild/aix-ppc64': 0.23.1
315 | '@esbuild/android-arm': 0.23.1
316 | '@esbuild/android-arm64': 0.23.1
317 | '@esbuild/android-x64': 0.23.1
318 | '@esbuild/darwin-arm64': 0.23.1
319 | '@esbuild/darwin-x64': 0.23.1
320 | '@esbuild/freebsd-arm64': 0.23.1
321 | '@esbuild/freebsd-x64': 0.23.1
322 | '@esbuild/linux-arm': 0.23.1
323 | '@esbuild/linux-arm64': 0.23.1
324 | '@esbuild/linux-ia32': 0.23.1
325 | '@esbuild/linux-loong64': 0.23.1
326 | '@esbuild/linux-mips64el': 0.23.1
327 | '@esbuild/linux-ppc64': 0.23.1
328 | '@esbuild/linux-riscv64': 0.23.1
329 | '@esbuild/linux-s390x': 0.23.1
330 | '@esbuild/linux-x64': 0.23.1
331 | '@esbuild/netbsd-x64': 0.23.1
332 | '@esbuild/openbsd-arm64': 0.23.1
333 | '@esbuild/openbsd-x64': 0.23.1
334 | '@esbuild/sunos-x64': 0.23.1
335 | '@esbuild/win32-arm64': 0.23.1
336 | '@esbuild/win32-ia32': 0.23.1
337 | '@esbuild/win32-x64': 0.23.1
338 |
339 | fsevents@2.3.2:
340 | optional: true
341 |
342 | fsevents@2.3.3:
343 | optional: true
344 |
345 | get-tsconfig@4.8.1:
346 | dependencies:
347 | resolve-pkg-maps: 1.0.0
348 |
349 | meow@13.2.0: {}
350 |
351 | p-limit@6.1.0:
352 | dependencies:
353 | yocto-queue: 1.1.1
354 |
355 | playwright-core@1.47.0: {}
356 |
357 | playwright@1.47.0:
358 | dependencies:
359 | playwright-core: 1.47.0
360 | optionalDependencies:
361 | fsevents: 2.3.2
362 |
363 | resolve-pkg-maps@1.0.0: {}
364 |
365 | toml@3.0.0: {}
366 |
367 | tsx@4.19.1:
368 | dependencies:
369 | esbuild: 0.23.1
370 | get-tsconfig: 4.8.1
371 | optionalDependencies:
372 | fsevents: 2.3.3
373 |
374 | undici-types@6.19.8: {}
375 |
376 | yocto-queue@1.1.1: {}
377 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | ## Rust Books PDF
2 |
3 | Please find the latest version of the pdf in the [release tab](https://github.com/shirshak55/Rust-Book-In-PDF/releases/). Look at the Assets section and download the pdf from there.
4 |
5 | ### Contributing
6 |
7 | Feel free to send a pull request. We follow the Rust Code of Conduct.
8 |
9 |
10 | ### Development
11 | To run this project, please install Node JS V20 or above. You can use any package manager like npm, yarn, pnpm etc.
12 |
13 | ```bash
14 | git clone https://github.com/shirshak55/Rust-Book-In-PDF.git
15 | pnpm install
16 | pnpm start
17 | ```
18 |
19 | This will run the project and download all the books in the config.toml file. You can also run `yarn start` with `DEBUG_ONLY_FRIST=true` to only download the first page of the book for easier debugging.
20 |
21 | ### Support us
22 |
23 | You can support us by starring the repo. As the book is written by other people, I can't take any financial support.
24 |
25 | ### Thanks,
26 |
27 | - Shirshak
28 | - TRPL team
29 | - Rustaceans
30 | - Contributors
31 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "esnext",
4 | "strict": true,
5 | "module": "esnext",
6 | "moduleResolution": "node",
7 | "isolatedModules": true,
8 | "esModuleInterop": true,
9 | "inlineSourceMap": true,
10 | "skipLibCheck": true,
11 | "lib": ["esnext", "dom"],
12 | "outDir": "./dist",
13 | "rootDir": "./src"
14 | },
15 | "exclude": ["node_modules"],
16 | "files": ["main.ts"]
17 | }
18 |
--------------------------------------------------------------------------------