diff --git a/assets/_main.scss b/assets/_main.scss index c854336..9202470 100644 --- a/assets/_main.scss +++ b/assets/_main.scss @@ -148,7 +148,7 @@ body[dir="rtl"] .book-menu { } .book-section-flat { - margin: $padding-16 * 2 0; + margin: $padding-16 0; > a, > span, diff --git a/assets/indices/contentIndex.json b/assets/indices/contentIndex.json index 924bbb9..843b45a 100644 --- a/assets/indices/contentIndex.json +++ b/assets/indices/contentIndex.json @@ -5,262 +5,442 @@ "lastmodified": "2022-12-31T02:09:59.91496047Z", "tags": null }, - "/docs/example/": { - "title": "Example Site", - "content": "\n# Introduction\n\n## Ferre hinnitibus erat accipitrem dixi Troiae tollens\n\nLorem markdownum, a quoque nutu est *quodcumque mandasset* veluti. Passim\ninportuna totidemque nympha fert; repetens pendent, poenarum guttura sed vacet\nnon, mortali undas. Omnis pharetramque gramen portentificisque membris servatum\nnovabis fallit de nubibus atque silvas mihi. **Dixit repetitaque Quid**; verrit\nlonga; sententia [mandat](http://pastor-ad.io/questussilvas) quascumque nescio\nsolebat [litore](http://lacrimas-ab.net/); noctes. *Hostem haerentem* circuit\n[plenaque tamen](http://www.sine.io/in).\n\n- Pedum ne indigenae finire invergens carpebat\n- Velit posses summoque\n- De fumos illa foret\n\n## Est simul fameque tauri qua ad\n\nLocum nullus nisi vomentes. Ab Persea sermone vela, miratur aratro; eandem\nArgolicas gener.\n\n## Me sol\n\nNec dis certa fuit socer, Nonacria **dies** manet tacitaque sibi? Sucis est\niactata Castrumque iudex, et iactato quoque terraeque es tandem et maternos\nvittis. Lumina litus bene poenamque animos callem ne tuas in leones illam dea\ncadunt genus, et pleno nunc in quod. Anumque crescentesque sanguinis\n[progenies](http://www.late.net/alimentavirides) nuribus rustica tinguet. Pater\nomnes liquido creditis noctem.\n\n if (mirrored(icmp_dvd_pim, 3, smbMirroredHard) != lion(clickImportQueue,\n viralItunesBalancing, bankruptcy_file_pptp)) {\n file += ip_cybercrime_suffix;\n }\n if (runtimeSmartRom == netMarketingWord) {\n virusBalancingWin *= scriptPromptBespoke + raster(post_drive,\n windowsSli);\n cd = address_hertz_trojan;\n soap_ccd.pcbServerGigahertz(asp_hardware_isa, offlinePeopleware, nui);\n } else {\n megabyte.api = modem_flowchart - web + syntaxHalftoneAddress;\n }\n if (3 \u003c mebibyteNetworkAnimated) {\n pharming_regular_error *= jsp_ribbon + algorithm * recycleMediaKindle(\n dvrSyntax, cdma);\n adf_sla *= hoverCropDrive;\n templateNtfs = -1 - vertical;\n } else {\n expressionCompressionVariable.bootMulti = white_eup_javascript(\n table_suffix);\n guidPpiPram.tracerouteLinux += rtfTerabyteQuicktime(1,\n managementRosetta(webcamActivex), 740874);\n }\n var virusTweetSsl = nullGigo;\n\n## Trepident sitimque\n\nSentiet et ferali errorem fessam, coercet superbus, Ascaniumque in pennis\nmediis; dolor? Vidit imi **Aeacon** perfida propositos adde, tua Somni Fluctibus\nerrante lustrat non.\n\nTamen inde, vos videt e flammis Scythica parantem rupisque pectora umbras. Haec\nficta canistris repercusso simul ego aris Dixit! Esse Fama trepidare hunc\ncrescendo vigor ululasse vertice *exspatiantur* celer tepidique petita aversata\noculis iussa est me ferro.\n", - "lastmodified": "2022-12-31T01:56:53.430566995Z", - "tags": null - }, - "/docs/example/collapsed/": { + "/configuration/": { "title": "", "content": "", - "lastmodified": "2022-12-31T01:56:53.430566995Z", + "lastmodified": "2023-01-05T06:57:26.743516296Z", "tags": null }, - "/docs/example/collapsed/3rd-level/": { - "title": "", - "content": "# 3rd Level of Menu\n\nNefas discordemque domino montes numen tum humili nexilibusque exit, Iove. Quae\nmiror esse, scelerisque Melaneus viribus. Miseri laurus. Hoc est proposita me\nante aliquid, aura inponere candidioribus quidque accendit bella, sumpta.\nIntravit quam erat figentem hunc, motus de fontes parvo tempestate.\n\n iscsi_virus = pitch(json_in_on(eupViral),\n northbridge_services_troubleshooting, personal(\n firmware_rw.trash_rw_crm.device(interactive_gopher_personal,\n software, -1), megabit, ergonomicsSoftware(cmyk_usb_panel,\n mips_whitelist_duplex, cpa)));\n if (5) {\n managementNetwork += dma - boolean;\n kilohertz_token = 2;\n honeypot_affiliate_ergonomics = fiber;\n }\n mouseNorthbridge = byte(nybble_xmp_modem.horse_subnet(\n analogThroughputService * graphicPoint, drop(daw_bit, dnsIntranet),\n gateway_ospf), repository.domain_key.mouse(serverData(fileNetwork,\n trim_duplex_file), cellTapeDirect, token_tooltip_mashup(\n ripcordingMashup)));\n module_it = honeypot_driver(client_cold_dvr(593902, ripping_frequency) +\n coreLog.joystick(componentUdpLink), windows_expansion_touchscreen);\n bashGigabit.external.reality(2, server_hardware_codec.flops.ebookSampling(\n ciscNavigationBacklink, table + cleanDriver), indexProtocolIsp);\n", - "lastmodified": "2022-12-31T01:56:53.430566995Z", - "tags": null - }, - "/docs/example/collapsed/3rd-level/4th-level": { - "title": "", - "content": "# 4th Level of Menu\n\n## Caesorum illa tu sentit micat vestes papyriferi\n\nInde aderam facti; Theseus vis de tauri illa peream. Oculos **uberaque** non\nregisque vobis cursuque, opus venit quam vulnera. Et maiora necemque, lege modo;\ngestanda nitidi, vero? Dum ne pectoraque testantur.\n\nVenasque repulsa Samos qui, exspectatum eram animosque hinc, [aut\nmanes](http://www.creveratnon.net/apricaaetheriis), Assyrii. Cupiens auctoribus\npariter rubet, profana magni super nocens. Vos ius sibilat inpar turba visae\niusto! Sedes ante dum superest **extrema**.\n", - "lastmodified": "2022-12-31T01:56:53.430566995Z", - "tags": null - }, - "/docs/example/hidden": { - "title": "", - "content": "\n# This page is hidden in menu\n\n# Quondam non pater est dignior ille Eurotas\n\n## Latent te facies\n\nLorem markdownum arma ignoscas vocavit quoque ille texit mandata mentis ultimus,\nfrementes, qui in vel. Hippotades Peleus [pennas\nconscia](http://gratia.net/tot-qua.php) cuiquam Caeneus quas.\n\n- Pater demittere evincitque reddunt\n- Maxime adhuc pressit huc Danaas quid freta\n- Soror ego\n- Luctus linguam saxa ultroque prior Tatiumque inquit\n- Saepe liquitur subita superata dederat Anius sudor\n\n## Cum honorum Latona\n\nO fallor [in sustinui\niussorum](http://www.spectataharundine.org/aquas-relinquit.html) equidem.\nNymphae operi oris alii fronde parens dumque, in auro ait mox ingenti proxima\niamdudum maius?\n\n reality(burnDocking(apache_nanometer),\n pad.property_data_programming.sectorBrowserPpga(dataMask, 37,\n recycleRup));\n intellectualVaporwareUser += -5 * 4;\n traceroute_key_upnp /= lag_optical(android.smb(thyristorTftp));\n surge_host_golden = mca_compact_device(dual_dpi_opengl, 33,\n commerce_add_ppc);\n if (lun_ipv) {\n verticalExtranet(1, thumbnail_ttl, 3);\n bar_graphics_jpeg(chipset - sector_xmp_beta);\n }\n\n## Fronde cetera dextrae sequens pennis voce muneris\n\nActa cretus diem restet utque; move integer, oscula non inspirat, noctisque\nscelus! Nantemque in suas vobis quamvis, et labori!\n\n var runtimeDiskCompiler = home - array_ad_software;\n if (internic \u003e disk) {\n emoticonLockCron += 37 + bps - 4;\n wan_ansi_honeypot.cardGigaflops = artificialStorageCgi;\n simplex -= downloadAccess;\n }\n var volumeHardeningAndroid = pixel + tftp + onProcessorUnmount;\n sector(memory(firewire + interlaced, wired));", - "lastmodified": "2022-12-31T01:56:53.430566995Z", - "tags": null - }, - "/docs/example/table-of-contents/": { - "title": "Table of Contents", - "content": "\n# Ubi loqui\n\n## Mentem genus facietque salire tempus bracchia\n\nLorem markdownum partu paterno Achillem. Habent amne generosi aderant ad pellem\nnec erat sustinet merces columque haec et, dixit minus nutrit accipiam subibis\nsubdidit. Temeraria servatum agros qui sed fulva facta. Primum ultima, dedit,\nsuo quisque linguae medentes fixo: tum petis.\n\n## Rapit vocant si hunc siste adspice\n\nOra precari Patraeque Neptunia, dixit Danae [Cithaeron\narmaque](http://mersis-an.org/litoristum) maxima in **nati Coniugis** templis\nfluidove. Effugit usus nec ingreditur agmen *ac manus* conlato. Nullis vagis\nnequiquam vultibus aliquos altera *suum venis* teneas fretum. Armos [remotis\nhoc](http://tutum.io/me) sine ferrea iuncta quam!\n\n## Locus fuit caecis\n\nNefas discordemque domino montes numen tum humili nexilibusque exit, Iove. Quae\nmiror esse, scelerisque Melaneus viribus. Miseri laurus. Hoc est proposita me\nante aliquid, aura inponere candidioribus quidque accendit bella, sumpta.\nIntravit quam erat figentem hunc, motus de fontes parvo tempestate.\n\n iscsi_virus = pitch(json_in_on(eupViral),\n northbridge_services_troubleshooting, personal(\n firmware_rw.trash_rw_crm.device(interactive_gopher_personal,\n software, -1), megabit, ergonomicsSoftware(cmyk_usb_panel,\n mips_whitelist_duplex, cpa)));\n if (5) {\n managementNetwork += dma - boolean;\n kilohertz_token = 2;\n honeypot_affiliate_ergonomics = fiber;\n }\n mouseNorthbridge = byte(nybble_xmp_modem.horse_subnet(\n analogThroughputService * graphicPoint, drop(daw_bit, dnsIntranet),\n gateway_ospf), repository.domain_key.mouse(serverData(fileNetwork,\n trim_duplex_file), cellTapeDirect, token_tooltip_mashup(\n ripcordingMashup)));\n module_it = honeypot_driver(client_cold_dvr(593902, ripping_frequency) +\n coreLog.joystick(componentUdpLink), windows_expansion_touchscreen);\n bashGigabit.external.reality(2, server_hardware_codec.flops.ebookSampling(\n ciscNavigationBacklink, table + cleanDriver), indexProtocolIsp);\n\n## Placabilis coactis nega ingemuit ignoscat nimia non\n\nFrontis turba. Oculi gravis est Delphice; *inque praedaque* sanguine manu non.\n\n if (ad_api) {\n zif += usb.tiffAvatarRate(subnet, digital_rt) + exploitDrive;\n gigaflops(2 - bluetooth, edi_asp_memory.gopher(queryCursor, laptop),\n panel_point_firmware);\n spyware_bash.statePopApplet = express_netbios_digital(\n insertion_troubleshooting.brouter(recordFolderUs), 65);\n }\n recursionCoreRay = -5;\n if (hub == non) {\n portBoxVirus = soundWeb(recursive_card(rwTechnologyLeopard),\n font_radcab, guidCmsScalable + reciprocalMatrixPim);\n left.bug = screenshot;\n } else {\n tooltipOpacity = raw_process_permalink(webcamFontUser, -1);\n executable_router += tape;\n }\n if (tft) {\n bandwidthWeb *= social_page;\n } else {\n regular += 611883;\n thumbnail /= system_lag_keyboard;\n }\n\n## Caesorum illa tu sentit micat vestes papyriferi\n\nInde aderam facti; Theseus vis de tauri illa peream. Oculos **uberaque** non\nregisque vobis cursuque, opus venit quam vulnera. Et maiora necemque, lege modo;\ngestanda nitidi, vero? Dum ne pectoraque testantur.\n\nVenasque repulsa Samos qui, exspectatum eram animosque hinc, [aut\nmanes](http://www.creveratnon.net/apricaaetheriis), Assyrii. Cupiens auctoribus\npariter rubet, profana magni super nocens. Vos ius sibilat inpar turba visae\niusto! Sedes ante dum superest **extrema**.\n", - "lastmodified": "2023-01-03T00:34:32.403382496Z", - "tags": null - }, - "/docs/example/table-of-contents/with-toc": { - "title": "With ToC", - "content": "# Caput vino delphine in tamen vias\n\n## Cognita laeva illo fracta\n\nLorem markdownum pavent auras, surgit nunc cingentibus libet **Laomedonque que**\nest. Pastor [An](http://est.org/ire.aspx) arbor filia foedat, ne [fugit\naliter](http://www.indiciumturbam.org/moramquid.php), per. Helicona illas et\ncallida neptem est *Oresitrophos* caput, dentibus est venit. Tenet reddite\n[famuli](http://www.antro-et.net/) praesentem fortibus, quaeque vis foret si\nfrondes *gelidos* gravidae circumtulit [inpulit armenta\nnativum](http://incurvasustulit.io/illi-virtute.html).\n\n1. Te at cruciabere vides rubentis manebo\n2. Maturuit in praetemptat ruborem ignara postquam habitasse\n3. Subitarum supplevit quoque fontesque venabula spretis modo\n4. Montis tot est mali quasque gravis\n5. Quinquennem domus arsit ipse\n6. Pellem turis pugnabant locavit\n\n## Natus quaerere\n\nPectora et sine mulcere, coniuge dum tincta incurvae. Quis iam; est dextra\nPeneosque, metuis a verba, primo. Illa sed colloque suis: magno: gramen, aera\nexcutiunt concipit.\n\n\u003e Phrygiae petendo suisque extimuit, super, pars quod audet! Turba negarem.\n\u003e Fuerat attonitus; et dextra retinet sidera ulnas undas instimulat vacuae\n\u003e generis? *Agnus* dabat et ignotis dextera, sic tibi pacis **feriente at mora**\n\u003e euhoeque *comites hostem* vestras Phineus. Vultuque sanguine dominoque [metuit\n\u003e risi](http://iuvat.org/eundem.php) fama vergit summaque meus clarissimus\n\u003e artesque tinguebat successor nominis cervice caelicolae.\n\n## Limitibus misere sit\n\nAurea non fata repertis praerupit feruntur simul, meae hosti lentaque *citius\nlevibus*, cum sede dixit, Phaethon texta. *Albentibus summos* multifidasque\niungitur loquendi an pectore, mihi ursaque omnia adfata, aeno parvumque in animi\nperlucentes. Epytus agis ait vixque clamat ornum adversam spondet, quid sceptra\nipsum **est**. Reseret nec; saeva suo passu debentia linguam terga et aures et\ncervix [de](http://www.amnem.io/pervenit.aspx) ubera. Coercet gelidumque manus,\ndoluit volvitur induta?\n\n## Enim sua\n\nIuvenilior filia inlustre templa quidem herbis permittat trahens huic. In\ncruribus proceres sole crescitque *fata*, quos quos; merui maris se non tamen\nin, mea.\n\n## Germana aves pignus tecta\n\nMortalia rudibusque caelum cognosceret tantum aquis redito felicior texit, nec,\naris parvo acre. Me parum contulerant multi tenentem, gratissime suis; vultum tu\noccupat deficeret corpora, sonum. E Actaea inplevit Phinea concepit nomenque\npotest sanguine captam nulla et, in duxisses campis non; mercede. Dicere cur\nLeucothoen obitum?\n\nPostibus mittam est *nubibus principium pluma*, exsecratur facta et. Iunge\nMnemonidas pallamque pars; vere restitit alis flumina quae **quoque**, est\nignara infestus Pyrrha. Di ducis terris maculatum At sede praemia manes\nnullaque!\n", - "lastmodified": "2022-12-31T01:56:53.430566995Z", - "tags": null - }, - "/docs/example/table-of-contents/without-toc": { - "title": "Without ToC", - "content": "\n# At me ipso nepotibus nunc celebratior genus\n\n## Tanto oblite\n\nLorem markdownum pectora novis patenti igne sua opus aurae feras materiaque\nillic demersit imago et aristas questaque posset. Vomit quoque suo inhaesuro\nclara. Esse cumque, per referri triste. Ut exponit solisque communis in tendens\nvincetis agisque iamque huic bene ante vetat omina Thebae rates. Aeacus servat\nadmonitu concidit, ad resimas vultus et rugas vultu **dignamque** Siphnon.\n\nQuam iugulum regia simulacra, plus meruit humo pecorumque haesit, ab discedunt\ndixit: ritu pharetramque. Exul Laurenti orantem modo, per densum missisque labor\nmanibus non colla unum, obiectat. Tu pervia collo, fessus quae Cretenque Myconon\ncrate! Tegumenque quae invisi sudore per vocari quaque plus ventis fluidos. Nodo\nperque, fugisse pectora sorores.\n\n## Summe promissa supple vadit lenius\n\nQuibus largis latebris aethera versato est, ait sentiat faciemque. Aequata alis\nnec Caeneus exululat inclite corpus est, ire **tibi** ostendens et tibi. Rigent\net vires dique possent lumina; **eadem** dixit poma funeribus paret et felix\nreddebant ventis utile lignum.\n\n1. Remansit notam Stygia feroxque\n2. Et dabit materna\n3. Vipereas Phrygiaeque umbram sollicito cruore conlucere suus\n4. Quarum Elis corniger\n5. Nec ieiunia dixit\n\nVertitur mos ortu ramosam contudit dumque; placabat ac lumen. Coniunx Amoris\nspatium poenamque cavernis Thebae Pleiadasque ponunt, rapiare cum quae parum\nnimium rima.\n\n## Quidem resupinus inducto solebat una facinus quae\n\nCredulitas iniqua praepetibus paruit prospexit, voce poena, sub rupit sinuatur,\nquin suum ventorumque arcadiae priori. Soporiferam erat formamque, fecit,\ninvergens, nymphae mutat fessas ait finge.\n\n1. Baculum mandataque ne addere capiti violentior\n2. Altera duas quam hoc ille tenues inquit\n3. Sicula sidereus latrantis domoque ratae polluit comites\n4. Possit oro clausura namque se nunc iuvenisque\n5. Faciem posuit\n6. Quodque cum ponunt novercae nata vestrae aratra\n\nIte extrema Phrygiis, patre dentibus, tonso perculit, enim blanda, manibus fide\nquos caput armis, posse! Nocendo fas Alcyonae lacertis structa ferarum manus\nfulmen dubius, saxa caelum effuge extremis fixum tumor adfecit **bella**,\npotentes? Dum nec insidiosa tempora tegit\n[spirarunt](http://mihiferre.net/iuvenes-peto.html). Per lupi pars foliis,\nporreximus humum negant sunt subposuere Sidone steterant auro. Memoraverit sine:\nferrum idem Orion caelum heres gerebat fixis?\n", - "lastmodified": "2022-12-31T01:56:53.430566995Z", - "tags": null - }, - "/docs/shortcodes/": { - "title": "", - "content": "", - "lastmodified": "2022-12-31T01:56:53.430566995Z", - "tags": null - }, - "/docs/shortcodes/buttons": { - "title": "", - "content": "# Buttons\n\nButtons are styled links that can lead to local page or external link.\n\n## Example\n\n```tpl\n{{\u003c/* button relref=\"/\" [class=\"...\"] */\u003e}}Get Home{{\u003c/* /button */\u003e}}\n{{\u003c/* button href=\"https://github.com/alex-shpak/hugo-book\" */\u003e}}Contribute{{\u003c/* /button */\u003e}}\n```\n\n{{\u003c button relref=\"/\" \u003e}}Get Home{{\u003c /button \u003e}}\n{{\u003c button href=\"https://github.com/alex-shpak/hugo-book\" \u003e}}Contribute{{\u003c /button \u003e}}\n", - "lastmodified": "2022-12-31T01:56:53.430566995Z", - "tags": null - }, - "/docs/shortcodes/columns": { - "title": "", - "content": "# Columns\n\nColumns help organize shorter pieces of content horizontally for readability.\n\n\n```html\n{{\u003c/* columns */\u003e}} \u003c!-- begin columns block --\u003e\n# Left Content\nLorem markdownum insigne...\n\n\u003c---\u003e \u003c!-- magic separator, between columns --\u003e\n\n# Mid Content\nLorem markdownum insigne...\n\n\u003c---\u003e \u003c!-- magic separator, between columns --\u003e\n\n# Right Content\nLorem markdownum insigne...\n{{\u003c/* /columns */\u003e}}\n```\n\n## Example\n\n{{\u003c columns \u003e}}\n## Left Content\nLorem markdownum insigne. Olympo signis Delphis! Retexi Nereius nova develat\nstringit, frustra Saturnius uteroque inter! Oculis non ritibus Telethusa\nprotulit, sed sed aere valvis inhaesuro Pallas animam: qui _quid_, ignes.\nMiseratus fonte Ditis conubia.\n\n\u003c---\u003e\n\n## Mid Content\nLorem markdownum insigne. Olympo signis Delphis! Retexi Nereius nova develat\nstringit, frustra Saturnius uteroque inter!\n\n\u003c---\u003e\n\n## Right Content\nLorem markdownum insigne. Olympo signis Delphis! Retexi Nereius nova develat\nstringit, frustra Saturnius uteroque inter! Oculis non ritibus Telethusa\nprotulit, sed sed aere valvis inhaesuro Pallas animam: qui _quid_, ignes.\nMiseratus fonte Ditis conubia.\n{{\u003c /columns \u003e}}\n", - "lastmodified": "2022-12-31T01:56:53.430566995Z", - "tags": null - }, - "/docs/shortcodes/details": { - "title": "", - "content": "# Details\n\nDetails shortcode is a helper for `details` html5 element. It is going to replace `expand` shortcode.\n\n## Example\n```tpl\n{{\u003c/* details \"Title\" [open] */\u003e}}\n## Markdown content\nLorem markdownum insigne...\n{{\u003c/* /details */\u003e}}\n```\n```tpl\n{{\u003c/* details title=\"Title\" open=true */\u003e}}\n## Markdown content\nLorem markdownum insigne...\n{{\u003c/* /details */\u003e}}\n```\n\n{{\u003c details \"Title\" open \u003e}}\n## Markdown content\nLorem markdownum insigne...\n{{\u003c /details \u003e}}\n", - "lastmodified": "2022-12-31T01:56:53.430566995Z", - "tags": null - }, - "/docs/shortcodes/expand": { - "title": "", - "content": "# Expand\n\nExpand shortcode can help to decrease clutter on screen by hiding part of text. Expand content by clicking on it.\n\n## Example\n### Default\n\n```tpl\n{{\u003c/* expand */\u003e}}\n## Markdown content\nLorem markdownum insigne...\n{{\u003c/* /expand */\u003e}}\n```\n\n{{\u003c expand \u003e}}\n## Markdown content\nLorem markdownum insigne...\n{{\u003c /expand \u003e}}\n\n### With Custom Label\n\n```tpl\n{{\u003c/* expand \"Custom Label\" \"...\" */\u003e}}\n## Markdown content\nLorem markdownum insigne...\n{{\u003c/* /expand */\u003e}}\n```\n\n{{\u003c expand \"Custom Label\" \"...\" \u003e}}\n## Markdown content\nLorem markdownum insigne. Olympo signis Delphis! Retexi Nereius nova develat\nstringit, frustra Saturnius uteroque inter! Oculis non ritibus Telethusa\nprotulit, sed sed aere valvis inhaesuro Pallas animam: qui _quid_, ignes.\nMiseratus fonte Ditis conubia.\n{{\u003c /expand \u003e}}\n", - "lastmodified": "2022-12-31T01:56:53.430566995Z", - "tags": null - }, - "/docs/shortcodes/hints": { - "title": "", - "content": "# Hints\n\nHint shortcode can be used as hint/alerts/notification block. \nThere are 3 colors to choose: `info`, `warning` and `danger`.\n\n```tpl\n{{\u003c/* hint [info|warning|danger] */\u003e}}\n**Markdown content** \nLorem markdownum insigne. Olympo signis Delphis! Retexi Nereius nova develat\nstringit, frustra Saturnius uteroque inter! Oculis non ritibus Telethusa\n{{\u003c/* /hint */\u003e}}\n```\n\n## Example\n\n{{\u003c hint info \u003e}}\n**Markdown content** \nLorem markdownum insigne. Olympo signis Delphis! Retexi Nereius nova develat\nstringit, frustra Saturnius uteroque inter! Oculis non ritibus Telethusa\n{{\u003c /hint \u003e}}\n\n{{\u003c hint warning \u003e}}\n**Markdown content** \nLorem markdownum insigne. Olympo signis Delphis! Retexi Nereius nova develat\nstringit, frustra Saturnius uteroque inter! Oculis non ritibus Telethusa\n{{\u003c /hint \u003e}}\n\n{{\u003c hint danger \u003e}}\n**Markdown content** \nLorem markdownum insigne. Olympo signis Delphis! Retexi Nereius nova develat\nstringit, frustra Saturnius uteroque inter! Oculis non ritibus Telethusa\n{{\u003c /hint \u003e}}\n", - "lastmodified": "2022-12-31T01:56:53.430566995Z", - "tags": null - }, - "/docs/shortcodes/katex": { - "title": "", - "content": "# KaTeX\n\nKaTeX shortcode let you render math typesetting in markdown document. See [KaTeX](https://katex.org/)\n\n## Example\n{{\u003c columns \u003e}}\n\n```latex\n{{\u003c/*/* katex [display] [class=\"text-center\"] */*/\u003e}}\nf(x) = \\int_{-\\infty}^\\infty\\hat f(\\xi)\\,e^{2 \\pi i \\xi x}\\,d\\xi\n{{\u003c/*/* /katex */*/\u003e}}\n```\n\n\u003c---\u003e\n\n{{\u003c katex display \u003e}}\nf(x) = \\int_{-\\infty}^\\infty\\hat f(\\xi)\\,e^{2 \\pi i \\xi x}\\,d\\xi\n{{\u003c /katex \u003e}}\n\n{{\u003c /columns \u003e}}\n\n## Display Mode Example\n\nHere is some inline example: {{\u003c katex \u003e}}\\pi(x){{\u003c /katex \u003e}}, rendered in the same line. And below is `display` example, having `display: block`\n{{\u003c katex display \u003e}}\nf(x) = \\int_{-\\infty}^\\infty\\hat f(\\xi)\\,e^{2 \\pi i \\xi x}\\,d\\xi\n{{\u003c /katex \u003e}}\nText continues here.\n", - "lastmodified": "2022-12-31T01:56:53.430566995Z", - "tags": null - }, - "/docs/shortcodes/mermaid": { - "title": "", - "content": "# Mermaid Chart\n\n[MermaidJS](https://mermaid-js.github.io/) is library for generating svg charts and diagrams from text.\n\n{{\u003c hint info \u003e}}\n**Override Mermaid Initialization Config**\n\nTo override the [initialization config](https://mermaid-js.github.io/mermaid/#/Setup) for Mermaid,\ncreate a `mermaid.json` file in your `assets` folder!\n{{\u003c /hint \u003e}}\n\n## Example\n\n{{\u003c columns \u003e}}\n```tpl\n{{\u003c/*/* mermaid [class=\"text-center\"]*/*/\u003e}}\nstateDiagram-v2\n State1: The state with a note\n note right of State1\n Important information! You can write\n notes.\n end note\n State1 --\u003e State2\n note left of State2 : This is the note to the left.\n{{\u003c/*/* /mermaid */*/\u003e}}\n```\n\n\u003c---\u003e\n\n{{\u003c mermaid \u003e}}\nstateDiagram-v2\n State1: The state with a note\n note right of State1\n Important information! You can write\n notes.\n end note\n State1 --\u003e State2\n note left of State2 : This is the note to the left.\n{{\u003c /mermaid \u003e}}\n\n{{\u003c /columns \u003e}}\n", - "lastmodified": "2022-12-31T01:56:53.430566995Z", - "tags": null - }, - "/docs/shortcodes/section/": { - "title": "", - "content": "\n# Section\n\nSection renders pages in section as definition list, using title and description.\n\n## Example\n\n```tpl\n{{\u003c/* section */\u003e}}\n```\n\n{{\u003csection\u003e}}\n", - "lastmodified": "2022-12-31T01:56:53.430566995Z", - "tags": null - }, - "/docs/shortcodes/section/first-page": { - "title": "", - "content": "# First page\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. \n\n\u003c!--more--\u003e\nDuis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n", - "lastmodified": "2022-12-31T01:56:53.430566995Z", - "tags": null - }, - "/docs/shortcodes/section/second-page": { - "title": "", - "content": "# Second Page\nLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n\n\u003c!--more--\u003e\nDuis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n\n", - "lastmodified": "2022-12-31T01:56:53.430566995Z", - "tags": null - }, - "/docs/shortcodes/tabs": { - "title": "", - "content": "# Tabs\n\nTabs let you organize content by context, for example installation instructions for each supported platform.\n\n```tpl\n{{\u003c/* tabs \"uniqueid\" */\u003e}}\n{{\u003c/* tab \"MacOS\" */\u003e}} # MacOS Content {{\u003c/* /tab */\u003e}}\n{{\u003c/* tab \"Linux\" */\u003e}} # Linux Content {{\u003c/* /tab */\u003e}}\n{{\u003c/* tab \"Windows\" */\u003e}} # Windows Content {{\u003c/* /tab */\u003e}}\n{{\u003c/* /tabs */\u003e}}\n```\n\n## Example\n\n{{\u003c tabs \"uniqueid\" \u003e}}\n{{\u003c tab \"MacOS\" \u003e}}\n# MacOS\n\nThis is tab **MacOS** content.\n\nLorem markdownum insigne. Olympo signis Delphis! Retexi Nereius nova develat\nstringit, frustra Saturnius uteroque inter! Oculis non ritibus Telethusa\nprotulit, sed sed aere valvis inhaesuro Pallas animam: qui _quid_, ignes.\nMiseratus fonte Ditis conubia.\n{{\u003c /tab \u003e}}\n\n{{\u003c tab \"Linux\" \u003e}}\n\n# Linux\n\nThis is tab **Linux** content.\n\nLorem markdownum insigne. Olympo signis Delphis! Retexi Nereius nova develat\nstringit, frustra Saturnius uteroque inter! Oculis non ritibus Telethusa\nprotulit, sed sed aere valvis inhaesuro Pallas animam: qui _quid_, ignes.\nMiseratus fonte Ditis conubia.\n{{\u003c /tab \u003e}}\n\n{{\u003c tab \"Windows\" \u003e}}\n\n# Windows\n\nThis is tab **Windows** content.\n\nLorem markdownum insigne. Olympo signis Delphis! Retexi Nereius nova develat\nstringit, frustra Saturnius uteroque inter! Oculis non ritibus Telethusa\nprotulit, sed sed aere valvis inhaesuro Pallas animam: qui _quid_, ignes.\nMiseratus fonte Ditis conubia.\n{{\u003c /tab \u003e}}\n{{\u003c /tabs \u003e}}\n", - "lastmodified": "2022-12-31T01:56:53.430566995Z", - "tags": null - }, - "/menu": { - "title": "", - "content": "\n- [**Example Site**]({{\u003c relref \"/docs/example\" \u003e}})\n- [Table of Contents]({{\u003c relref \"/docs/example/table-of-contents\" \u003e}})\n - [With ToC]({{\u003c relref \"/docs/example/table-of-contents/with-toc\" \u003e}})\n - [Without ToC]({{\u003c relref \"/docs/example/table-of-contents/without-toc\" \u003e}})\n- [Collapsed]({{\u003c relref \"/docs/example/collapsed\" \u003e}})\n - [3rd]({{\u003c relref \"/docs/example/collapsed/3rd-level\" \u003e}})\n - [4th]({{\u003c relref \"/docs/example/collapsed/3rd-level/4th-level\" \u003e}})\n\u003cbr /\u003e\n\n- **Shortcodes**\n- [Buttons]({{\u003c relref \"/docs/shortcodes/buttons\" \u003e}})\n- [Columns]({{\u003c relref \"/docs/shortcodes/columns\" \u003e}})\n- [Expand]({{\u003c relref \"/docs/shortcodes/expand\" \u003e}})\n- [Hints]({{\u003c relref \"/docs/shortcodes/hints\" \u003e}})\n- [KaTex]({{\u003c relref \"/docs/shortcodes/katex\" \u003e}})\n- [Mermaid]({{\u003c relref \"/docs/shortcodes/mermaid\" \u003e}})\n- [Tabs]({{\u003c relref \"/docs/shortcodes/tabs\" \u003e}})\n\u003cbr /\u003e\n", - "lastmodified": "2022-12-31T01:56:53.430566995Z", - "tags": null - }, - "/notes/": { - "title": "Test Notes", - "content": "\n# Hello World", - "lastmodified": "2022-12-31T08:24:36.270068358Z", - "tags": null - }, - "/notes/CJK-+-Latex-Support-%E6%B5%8B%E8%AF%95": { - "title": "CJK + Latex Support (测试)", - "content": "\n## Chinese, Japanese, Korean Support\n几乎在我们意识到之前,我们已经离开了地面。\n\n우리가 그것을 알기도 전에 우리는 땅을 떠났습니다.\n\n私たちがそれを知るほぼ前に、私たちは地面を離れていました。\n\n## Latex\n\nBlock math works with two dollar signs `$$...$$`\n\n$$f(x) = \\int_{-\\infty}^\\infty\n f\\hat(\\xi),e^{2 \\pi i \\xi x}\n \\,d\\xi$$\n\t\nInline math also works with single dollar signs `$...$`. For example, Euler's identity but inline: $e^{i\\pi} = -1$\n\nAligned equations work quite well:\n\n$$\n\\begin{aligned}\na \u0026= b + c \\\\ \u0026= e + f \\\\\n\\end{aligned}\n$$\n\nAnd matrices\n\n$$\n\\begin{bmatrix}\n1 \u0026 2 \u0026 3 \\\\\na \u0026 b \u0026 c\n\\end{bmatrix}\n$$\n\n## RTL\nMore information on configuring RTL languages like Arabic in the [config](notes/config.md) page.\n", - "lastmodified": "2022-12-31T02:53:43.340377422Z", - "tags": null - }, - "/notes/callouts": { - "title": "Callouts", - "content": "\n## Callout support\n\nQuartz supports the same Admonition-callout syntax as Obsidian.\n\nThis includes\n- 12 Distinct callout types (each with several aliases)\n- Collapsable callouts\n\nSee [documentation on supported types and syntax here](https://help.obsidian.md/How+to/Use+callouts#Types).\n\n## Showcase\n\n\u003e [!EXAMPLE] Examples\n\u003e\n\u003e Aliases: example\n\n\u003e [!note] Notes\n\u003e\n\u003e Aliases: note\n\n\u003e [!abstract] Summaries \n\u003e\n\u003e Aliases: abstract, summary, tldr\n\n\u003e [!info] Info \n\u003e\n\u003e Aliases: info, todo\n\n\u003e [!tip] Hint \n\u003e\n\u003e Aliases: tip, hint, important\n\n\u003e [!success] Success \n\u003e\n\u003e Aliases: success, check, done\n\n\u003e [!question] Question \n\u003e\n\u003e Aliases: question, help, faq\n\n\u003e [!warning] Warning \n\u003e\n\u003e Aliases: warning, caution, attention\n\n\u003e [!failure] Failure \n\u003e\n\u003e Aliases: failure, fail, missing\n\n\u003e [!danger] Error\n\u003e\n\u003e Aliases: danger, error\n\n\u003e [!bug] Bug\n\u003e\n\u003e Aliases: bug\n\n\u003e [!quote] Quote\n\u003e\n\u003e Aliases: quote, cite\n", - "lastmodified": "2022-12-31T02:53:43.340377422Z", - "tags": null - }, - "/notes/config": { + "/configuration/config": { "title": "Configuration", "content": "\n## Configuration\nQuartz is designed to be extremely configurable. You can find the bulk of the configuration scattered throughout the repository depending on how in-depth you'd like to get.\n\nThe majority of configuration can be found under `data/config.yaml`. An annotated example configuration is shown below.\n\n```yaml {title=\"data/config.yaml\"}\n# The name to display in the footer\nname: Jacky Zhao\n\n# whether to globally show the table of contents on each page\n# this can be turned off on a per-page basis by adding this to the\n# front-matter of that note\nenableToc: true\n\n# whether to by-default open or close the table of contents on each page\nopenToc: false\n\n# whether to display on-hover link preview cards\nenableLinkPreview: true\n\n# whether to render titles for code blocks\nenableCodeBlockTitle: true \n\n# whether to render copy buttons for code blocks\nenableCodeBlockCopy: true \n\n# whether to render callouts\nenableCallouts: true\n\n# whether to try to process Latex\nenableLatex: true\n\n# whether to enable single-page-app style rendering\n# this prevents flashes of unstyled content and improves\n# smoothness of Quartz. More info in issue #109 on GitHub\nenableSPA: true\n\n# whether to render a footer\nenableFooter: true\n\n# whether backlinks of pages should show the context in which\n# they were mentioned\nenableContextualBacklinks: true\n\n# whether to show a section of recent notes on the home page\nenableRecentNotes: false\n\n# whether to display an 'edit' button next to the last edited field\n# that links to github\nenableGitHubEdit: true\nGitHubLink: https://github.com/jackyzha0/quartz/tree/hugo/content\n\n# whether to render mermaid diagrams\nenableMermaid: true\n\n# whether to use Operand to power semantic search\n# IMPORTANT: replace this API key with your own if you plan on using\n# Operand search!\nsearch:\n enableSemanticSearch: false\n operandApiKey: \"REPLACE-WITH-YOUR-OPERAND-API-KEY\"\n operandIndexId: \"REPLACE-WITH-YOUR-OPERAND-INDEX-ID\"\n\n# page description used for SEO\ndescription:\n Host your second brain and digital garden for free. Quartz features extremely fast full-text search,\n Wikilink support, backlinks, local graph, tags, and link previews.\n\n# title of the home page (also for SEO)\npage_title:\n \"🪴 Quartz 3.3\"\n\n# links to show in the footer\nlinks:\n - link_name: Twitter\n link: https://twitter.com/_jzhao\n - link_name: Github\n link: https://github.com/jackyzha0\n```\n\n### Code Block Titles\nTo add code block titles with Quartz:\n\n1. Ensure that code block titles are enabled in Quartz's configuration:\n\n ```yaml {title=\"data/config.yaml\", linenos=false}\n enableCodeBlockTitle: true\n ```\n\n2. Add the `title` attribute to the desired [code block\n fence](https://gohugo.io/content-management/syntax-highlighting/#highlighting-in-code-fences):\n\n ```markdown {linenos=false}\n ```yaml {title=\"data/config.yaml\"}\n enableCodeBlockTitle: true # example from step 1\n ```\n ```\n\n**Note** that if `{title=\u003cmy-title\u003e}` is included, and code block titles are not\nenabled, no errors will occur, and the title attribute will be ignored.\n\n### HTML Favicons\nIf you would like to customize the favicons of your Quartz-based website, you \ncan add them to the `data/config.yaml` file. The **default** without any set \n`favicon` key is:\n\n```html {title=\"layouts/partials/head.html\", linenostart=15}\n\u003clink rel=\"shortcut icon\" href=\"icon.png\" type=\"image/png\"\u003e\n```\n\nThe default can be overridden by defining a value to the `favicon` key in your \n`data/config.yaml` file. For example, here is a `List[Dictionary]` example format, which is\nequivalent to the default:\n\n```yaml {title=\"data/config.yaml\", linenos=false}\nfavicon:\n - { rel: \"shortcut icon\", href: \"icon.png\", type: \"image/png\" }\n# - { ... } # Repeat for each additional favicon you want to add\n```\n\nIn this format, the keys are identical to their HTML representations.\n\nIf you plan to add multiple favicons generated by a website (see list below), it\nmay be easier to define it as HTML. Here is an example which appends the \n**Apple touch icon** to Quartz's default favicon:\n\n```yaml {title=\"data/config.yaml\", linenos=false}\nfavicon: |\n \u003clink rel=\"shortcut icon\" href=\"icon.png\" type=\"image/png\"\u003e\n \u003clink rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"/apple-touch-icon.png\"\u003e\n```\n\nThis second favicon will now be used as a web page icon when someone adds your \nwebpage to the home screen of their Apple device. If you are interested in more \ninformation about the current and past standards of favicons, you can read \n[this article](https://www.emergeinteractive.com/insights/detail/the-essentials-of-favicons/).\n\n**Note** that all generated favicon paths, defined by the `href` \nattribute, are relative to the `static/` directory.\n\n### Graph View\nTo customize the Interactive Graph view, you can poke around `data/graphConfig.yaml`.\n\n```yaml {title=\"data/graphConfig.yaml\"}\n# if true, a Global Graph will be shown on home page with full width, no backlink.\n# A different set of Local Graphs will be shown on sub pages.\n# if false, Local Graph will be default on every page as usual\nenableGlobalGraph: false\n\n### Local Graph ###\nlocalGraph:\n # whether automatically generate a legend\n enableLegend: false\n \n # whether to allow dragging nodes in the graph\n enableDrag: true\n \n # whether to allow zooming and panning the graph\n enableZoom: true\n \n # how many neighbours of the current node to show (-1 is all nodes)\n depth: 1\n \n # initial zoom factor of the graph\n scale: 1.2\n \n # how strongly nodes should repel each other\n repelForce: 2\n\n # how strongly should nodes be attracted to the center of gravity\n centerForce: 1\n\n # what the default link length should be\n linkDistance: 1\n \n # how big the node labels should be\n fontSize: 0.6\n \n # scale at which to start fading the labes on nodes\n opacityScale: 3\n\n### Global Graph ###\nglobalGraph:\n\t# same settings as above\n\n### For all graphs ###\n# colour specific nodes path off of their path\npaths:\n - /moc: \"#4388cc\"\n```\n\n\n## Styling\nWant to go even more in-depth? You can add custom CSS styling and change existing colours through editing `assets/styles/custom.scss`. If you'd like to target specific parts of the site, you can add ids and classes to the HTML partials in `/layouts/partials`. \n\n### Partials\nPartials are what dictate what gets rendered to the page. Want to change how pages are styled and structured? You can edit the appropriate layout in `/layouts`.\n\nFor example, the structure of the home page can be edited through `/layouts/index.html`. To customize the footer, you can edit `/layouts/partials/footer.html`\n\nMore info about partials on [Hugo's website.](https://gohugo.io/templates/partials/)\n\nStill having problems? Checkout our [FAQ and Troubleshooting guide](notes/troubleshooting.md).\n\n## Language Support\n[CJK + Latex Support (测试)](notes/CJK%20+%20Latex%20Support%20(测试).md) comes out of the box with Quartz.\n\nWant to support languages that read from right-to-left (like Arabic)? Hugo (and by proxy, Quartz) supports this natively.\n\nFollow the steps [Hugo provides here](https://gohugo.io/content-management/multilingual/#configure-languages) and modify your `config.toml`\n\nFor example:\n\n```toml\ndefaultContentLanguage = 'ar'\n[languages]\n [languages.ar]\n languagedirection = 'rtl'\n title = 'مدونتي'\n weight = 1\n```\n", "lastmodified": "2022-12-31T02:53:43.344377399Z", "tags": null }, - "/notes/custom-Domain": { + "/configuration/custom-Domain": { "title": "Custom Domain", "content": "\n### Registrar\nThis step is only applicable if you are using a **custom domain**! If you are using a `\u003cYOUR-USERNAME\u003e.github.io` domain, you can skip this step.\n\nFor this last bit to take effect, you also need to create a CNAME record with the DNS provider you register your domain with (i.e. NameCheap, Google Domains).\n\nGitHub has some [documentation on this](https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/managing-a-custom-domain-for-your-github-pages-site), but the tldr; is to\n\n1. Go to your forked repository (`github.com/\u003cYOUR-GITHUB-USERNAME\u003e/quartz`) settings page and go to the Pages tab. Under \"Custom domain\", type your custom domain, then click **Save**.\n2. Go to your DNS Provider and create a CNAME record that points from your domain to `\u003cYOUR-GITHUB-USERNAME.github.io.` (yes, with the trailing period).\n\n\t![Example Configuration for Quartz](/notes/images/google-domains.png)*Example Configuration for Quartz*\n3. Wait 30 minutes to an hour for the network changes to kick in.\n4. Done!", "lastmodified": "2022-12-31T02:53:43.344377399Z", "tags": null }, - "/notes/docker": { + "/configuration/docker": { "title": "Hosting with Docker", "content": "\nIf you want to host Quartz on a machine without using a webpage hosting service, it may be easier to [install Docker Compose](https://docs.docker.com/compose/install/) and follow the instructions below than to [install Quartz's dependencies manually](notes/preview%20changes.md).\n## Hosting Quartz Locally\nYou can serve Quartz locally at `http://localhost:1313` with the following script, replacing `/path/to/quartz` with the \nactual path to your Quartz folder.\n\ndocker-compose.yml\n```\nservices:\n quartz-hugo:\n image: ghcr.io/jackyzha0/quartz:hugo\n container_name: quartz-hugo\n volumes:\n - /path/to/quartz:/quartz\n ports:\n - 1313:1313\n\n # optional\n environment:\n - HUGO_BIND=0.0.0.0\n - HUGO_BASEURL=http://localhost\n - HUGO_PORT=1313\n - HUGO_APPENDPORT=true\n```\n\nThen run with: `docker-compose up -d` in the same directory as your `docker-compose.yml` file.\n\nWhile the container is running, you can update the `quartz` fork with: `docker exec -it quartz-hugo make update`.\n\n## Exposing Your Container to the Internet\n\n### To Your Public IP Address with Port Forwarding (insecure)\n\nAssuming you are already familiar with [port forwarding](https://en.wikipedia.org/wiki/Port_forwarding) and [setting it up with your router model](https://portforward.com):\n\n1. You should set the environment variable `HUGO_BASEURL=http://your-public-ip` and then start your container.\n2. Set up port forwarding on your router from port `p` to `your-local-ip:1313`.\n3. You should now be able to access Quartz from outside your local network at `http://your-public-ip:p`.\n\nHowever, your HTTP connection will be unencrypted and **this method is not secure**.\n\n### To a Domain using Cloudflare Proxy\n\n1. Port forward 443 (HTTPS) from your machine.\n2. Buy a custom domain (say, `your-domain.com`) from [Cloudflare](https://www.cloudflare.com/products/registrar/). Point a DNS A record from `your-domain.com` to your public IP address and enable the proxy.\n3. Set the environment variables `HUGO_BASEURL=https://your-domain.com`, `HUGO_PORT=443`, and `HUGO_APPENDPORT=false`. Change `1313:1313` to `443:443` for the `ports` in `docker-compose.yml`.\n4. Spin up your Quartz container and enjoy it at `https://your-domain.com`!\n\n### To a Domain using a Reverse Proxy\n\nIf you want to serve more than just Quartz to the internet on this machine (or don't want to use the Cloudflare registrar and proxy), you should follow the steps in the section above (as appropriate) and also set up a reverse proxy, like [Traefik](https://doc.traefik.io/traefik). Be sure to configure your TLS certificates too!\n", "lastmodified": "2022-12-31T02:53:43.344377399Z", "tags": null }, - "/notes/editing": { + "/configuration/editing": { "title": "Editing Content in Quartz", "content": "\n## Editing \nQuartz runs on top of [Hugo](https://gohugo.io/) so all notes are written in [Markdown](https://www.markdownguide.org/getting-started/).\n\n### Folder Structure\nHere's a rough overview of what's what.\n\n**All content in your garden can found in the `/content` folder.** To make edits, you can open any of the files and make changes directly and save it. You can organize content into any folder you'd like.\n\n**To edit the main home page, open `/content/_index.md`.**\n\nTo create a link between notes in your garden, just create a normal link using Markdown pointing to the document in question. Please note that **all links should be relative to the root `/content` path**. \n\n```markdown\nFor example, I want to link this current document to `notes/config.md`.\n[A link to the config page](notes/config.md)\n```\n\nSimilarly, you can put local images anywhere in the `/content` folder.\n\n```markdown\nExample image (source is in content/notes/images/example.png)\n![Example Image](/content/notes/images/example.png)\n```\n\nYou can also use wikilinks if that is what you are more comfortable with!\n\n### Front Matter\nHugo is picky when it comes to metadata for files. Make sure that your title is double-quoted and that you have a title defined at the top of your file like so. You can also add tags here as well.\n\n```yaml\n---\ntitle: \"Example Title\"\ntags:\n- example-tag\n---\n\nRest of your content here...\n```\n\n### Obsidian\nI recommend using [Obsidian](http://obsidian.md/) as a way to edit and grow your digital garden. It comes with a really nice editor and graphical interface to preview all of your local files.\n\nThis step is **highly recommended**.\n\n\u003e 🔗 Step 3: [How to setup your Obsidian Vault to work with Quartz](notes/obsidian.md)\n\n## Previewing Changes\nThis step is purely optional and mostly for those who want to see the published version of their digital garden locally before opening it up to the internet. This is *highly recommended* but not required.\n\n\u003e 👀 Step 4: [Preview Quartz Changes](notes/preview%20changes.md)\n\nFor those who like to live life more on the edge, viewing the garden through Obsidian gets you pretty close to the real thing.\n\n## Publishing Changes\nNow that you know the basics of managing your digital garden using Quartz, you can publish it to the internet!\n\n\u003e 🌍 Step 5: [Hosting Quartz online!](notes/hosting.md)\n\nHaving problems? Checkout our [FAQ and Troubleshooting guide](notes/troubleshooting.md).\n", "lastmodified": "2022-12-31T02:53:43.344377399Z", "tags": null }, - "/notes/hosting": { + "/configuration/hosting": { "title": "Deploying Quartz to the Web", "content": "\n## Hosting on GitHub Pages\nQuartz is designed to be effortless to deploy. If you forked and cloned Quartz directly from the repository, everything should already be good to go! Follow the steps below.\n\n### Enable GitHub Actions\nBy default, GitHub disables workflows from running automatically on Forked Repostories. Head to the 'Actions' tab of your forked repository and Enable Workflows to setup deploying your Quartz site!\n\n![Enable GitHub Actions](notes/images/github-actions.png)*Enable GitHub Actions*\n\n### Enable GitHub Pages\n\nHead to the 'Settings' tab of your forked repository and go to the 'Pages' tab.\n\n1. (IMPORTANT) Set the source to deploy from `master` (and not `hugo`) using `/ (root)`\n2. Set a custom domain here if you have one!\n\n![Enable GitHub Pages](/notes/images/github-pages.png)*Enable GitHub Pages*\n\n### Pushing Changes\nTo see your changes on the internet, we need to push it them to GitHub. Quartz is a `git` repository so updating it is the same workflow as you would follow as if it were just a regular software project.\n\n```shell\n# Navigate to Quartz folder\ncd \u003cpath-to-quartz\u003e\n\n# Commit all changes\ngit add .\ngit commit -m \"message describing changes\"\n\n# Push to GitHub to update site\ngit push origin hugo\n```\n\nNote: we specifically push to the `hugo` branch here. Our GitHub action automatically runs everytime a push to is detected to that branch and then updates the `master` branch for redeployment.\n\n### Setting up the Site\nNow let's get this site up and running. Never hosted a site before? No problem. Have a fancy custom domain you already own or want to subdomain your Quartz? That's easy too.\n\nHere, we take advantage of GitHub's free page hosting to deploy our site. Change `baseURL` in `/config.toml`. \n\nMake sure that your `baseURL` has a trailing `/`!\n\n[Reference `config.toml` here](https://github.com/jackyzha0/quartz/blob/hugo/config.toml)\n\n```toml\nbaseURL = \"https://\u003cYOUR-DOMAIN\u003e/\"\n```\n\nIf you are using this under a subdomain (e.g. `\u003cYOUR-GITHUB-USERNAME\u003e.github.io/quartz`), include the trailing `/`. **You need to do this especially if you are using GitHub!**\n\n```toml\nbaseURL = \"https://\u003cYOUR-GITHUB-USERNAME\u003e.github.io/quartz/\"\n```\n\nChange `cname` in `/.github/workflows/deploy.yaml`. Again, if you don't have a custom domain to use, you can use `\u003cYOUR-USERNAME\u003e.github.io`.\n\nPlease note that the `cname` field should *not* have any path `e.g. end with /quartz` or have a trailing `/`.\n\n[Reference `deploy.yaml` here](https://github.com/jackyzha0/quartz/blob/hugo/.github/workflows/deploy.yaml)\n\n```yaml {title=\".github/workflows/deploy.yaml\"}\n- name: Deploy \n uses: peaceiris/actions-gh-pages@v3 \n with: \n\tgithub_token: ${{ secrets.GITHUB_TOKEN }} # this can stay as is, GitHub fills this in for us!\n\tpublish_dir: ./public \n\tpublish_branch: master\n\tcname: \u003cYOUR-DOMAIN\u003e\n```\n\nHave a custom domain? [Learn how to set it up with Quartz ](notes/custom%20Domain.md).\n\n### Ignoring Files\nOnly want to publish a subset of all of your notes? Don't worry, Quartz makes this a simple two-step process.\n\n❌ [Excluding pages from being published](notes/ignore%20notes.md)\n\n## Docker Support\nIf you don't want to use a hosting service, you can host using [Docker](notes/docker.md) instead!\nI would *not use this method* unless you know what you are doing.\n\n---\n\nNow that your Quartz is live, let's figure out how to make Quartz really *yours*!\n\n\u003e Step 6: 🎨 [Customizing Quartz](notes/config.md)\n\nHaving problems? Checkout our [FAQ and Troubleshooting guide](notes/troubleshooting.md).\n", "lastmodified": "2023-01-01T23:44:35.436929149Z", "tags": null }, - "/notes/ignore-notes": { + "/configuration/ignore-notes": { "title": "Ignoring Notes", "content": "\n### Quartz Ignore\nEdit `ignoreFiles` in `config.toml` to include paths you'd like to exclude from being rendered.\n\n```toml\n...\nignoreFiles = [ \n \"/content/templates/*\", \n \"/content/private/*\", \n \"\u003cyour path here\u003e\"\n]\n```\n\n`ignoreFiles` supports the use of Regular Expressions (RegEx) so you can ignore patterns as well (e.g. ignoring all `.png`s by doing `\\\\.png$`).\nTo ignore a specific file, you can also add the tag `draft: true` to the frontmatter of a note.\n\n```markdown\n---\ntitle: Some Private Note\ndraft: true\n---\n...\n```\n\nMore details in [Hugo's documentation](https://gohugo.io/getting-started/configuration/#ignore-content-and-data-files-when-rendering).\n\n### Global Ignore\nHowever, just adding to the `ignoreFiles` will only prevent the page from being access through Quartz. If you want to prevent the file from being pushed to GitHub (for example if you have a public repository), you need to also add the path to the `.gitignore` file at the root of the repository.", "lastmodified": "2022-12-31T02:53:43.344377399Z", "tags": null }, - "/notes/obsidian": { + "/configuration/obsidian": { "title": "Obsidian Vault Integration", "content": "\n## Setup\nObsidian is the preferred way to use Quartz. You can either create a new Obsidian Vault or link one that your already have.\n\n### New Vault\nIf you don't have an existing Vault, [download Obsidian](https://obsidian.md/) and create a new Vault in the `/content` folder that you created and cloned during the [setup](notes/setup.md) step.\n\n### Linking an existing Vault\nThe easiest way to use an existing Vault is to copy all of your files (directory and hierarchies intact) into the `/content` folder.\n\n## Settings\nGreat, now that you have your Obsidian linked to your Quartz, let's fix some settings so that they play well.\n\n1. Under Options \u003e Files and Links, set the New link format to always use Absolute Path in Vault.\n2. Go to Settings \u003e Files \u0026 Links \u003e Turn \"on\" automatically update internal links.\n\n![Obsidian Settings](/notes/images/obsidian-settings.png)*Obsidian Settings*\n\n## Templates\nInserting front matter everytime you want to create a new Note gets annoying really quickly. Luckily, Obsidian supports templates which makes inserting new content really easily.\n\n**If you decide to overwrite the `/content` folder completely, don't remove the `/content/templates` folder!**\n\nHead over to Options \u003e Core Plugins and enable the Templates plugin. Then go to Options \u003e Hotkeys and set a hotkey for 'Insert Template' (I recommend `[cmd]+T`). That way, when you create a new note, you can just press the hotkey for a new template and be ready to go!\n\n\u003e 👀 Step 4: [Preview Quartz Changes](notes/preview%20changes.md)", "lastmodified": "2022-12-31T02:53:43.348377376Z", "tags": null }, - "/notes/philosophy": { - "title": "Quartz Philosophy", - "content": "\n\u003e “[One] who works with the door open gets all kinds of interruptions, but [they] also occasionally gets clues as to what the world is and what might be important.” — Richard Hamming\n\n## Why Quartz?\nHosting a public digital garden isn't easy. There are an overwhelming number of tutorials, resources, and guides for tools like [Notion](https://www.notion.so/), [Roam](https://roamresearch.com/), and [Obsidian](https://obsidian.md/), yet none of them have super easy to use *free* tools to publish that garden to the world.\n\nI've personally found that\n1. It's nice to access notes from anywhere\n2. Having a public digital garden invites open conversations\n3. It makes keeping personal notes and knowledge *playful and fun*\n\nI was really inspired by [Bianca](https://garden.bianca.digital/) and [Joel](https://joelhooks.com/digital-garden)'s digital gardens and wanted to try making my own.\n\n**The goal of Quartz is to make hosting your own public digital garden free and simple.** You don't even need your own website. Quartz does all of that for you and gives your own little corner of the internet.\n", - "lastmodified": "2022-12-31T02:53:43.348377376Z", - "tags": null - }, - "/notes/preview-changes": { + "/configuration/preview-changes": { "title": "Preview Changes", "content": "\nIf you'd like to preview what your Quartz site looks like before deploying it to the internet, the following\ninstructions guide you through installing the proper dependencies to run it locally.\n\n\n## Install `hugo-obsidian`\nThis step will generate the list of backlinks for Hugo to parse. Ensure you have [Go](https://golang.org/doc/install) (\u003e= 1.16) installed.\n\n```bash\n# Install and link `hugo-obsidian` locally\ngo install github.com/jackyzha0/hugo-obsidian@latest\n```\n\nIf you are running into an error saying that `command not found: hugo-obsidian`, make sure you set your `GOPATH` correctly! This will allow your terminal to correctly recognize hugo-obsidian as an executable.\n\nAfterwards, start the Hugo server as shown above and your local backlinks and interactive graph should be populated!\n\n## Installing Hugo\nHugo is the static site generator that powers Quartz. [Install Hugo with \"extended\" Sass/SCSS version](https://gohugo.io/getting-started/installing/) first. Then,\n\n```bash\n# Navigate to your local Quartz folder\ncd \u003clocation-of-your-local-quartz\u003e\n\n# Start local server\nmake serve\n\n# View your site in a browser at http://localhost:1313/\n```\n\n\u003e [!INFO] Docker Support\n\u003e\n\u003e If you have Docker installed already, open your terminal, navigate to your folder with Quartz and run `make docker`\n\nNow that you are happy with how your Quartz instance looks, let's get it hosted!\n\n\u003e 🌍 Step 5: [Hosting Quartz online!](notes/hosting.md)\n", "lastmodified": "2022-12-31T02:53:43.348377376Z", "tags": null }, - "/notes/search": { + "/configuration/search": { "title": "Search", "content": "\nQuartz supports two modes of searching through content.\n\n## Full-text\nFull-text search is the default in Quartz. It produces results that *exactly* match the search query. This is easier to setup but usually produces lower quality matches.\n\n```yaml {title=\"data/config.yaml\"}\n# the default option\nenableSemanticSearch: false\n```\n\n## Natural Language\nNatural language search is powered by [Operand](https://beta.operand.ai/). It understands language like a person does and finds results that best match user intent. In this sense, it is closer to how Google Search works.\n\nNatural language search tends to produce higher quality results than full-text search.\n\nHere's how to set it up.\n\n1. Login or Register for a new Operand account. Click the verification link sent to your email, and you'll be redirected to the dashboard. (Note) You do not need to enter a credit card to create an account, or get started with the Operand API. The first $10 of usage each month is free. To learn more, see pricing. If you go over your free quota, we'll (politely) reach out and ask you to configure billing.\n2. Create your first index. On the dashboard, under \"Indexes\", enter the name and description of your index, and click \"Create Index\". Note down the ID of the index (obtained by clicking on the index name in the list of indexes), as you'll need it in the next step. IDs are unique to each index, and look something like `uqv1duxxbdxu`.\n3. Click into the index you've created. Under \"Index Something\", select \"SITEMAP\" from the dropdown and click \"Add Source\".\n4. For the \"Sitemap.xml URL\", put your deployed site's base URL followed by `sitemap.xml`. For example, for `quartz.jzhao.xyz`, put `https://quartz.jzhao.xyz/sitemap.xml`. Leave the URL Regex empty. \n5. Get your API key. On the dashboard, under \"API Keys\", you can manage your API keys. If you don't already have an API key, click \"Create API Key\". You'll need this for the next step.\n6. Open `data/config.yaml`. Set `enableSemanticSearch` to `true`, `operandApiKey` to your copied key, and `operandIndexId` to the ID of the index we created from earlier..\n\n```yaml {title=\"data/config.yaml\"}\n# the default option\nsearch:\n enableSemanticSearch: true\n operandApiKey: \"jp9k5hudse2a828z98kxd6z3payi8u90rnjf\"\n operandIndexId: \"s0kf3bd6tldw\"\n```\n7. Push your changes to the site and wait for it to deploy.\n8. Check the Operand dashboard and wait for your site to index. Enjoy natural language search powered by Operand!\n", "lastmodified": "2022-12-31T02:53:43.348377376Z", "tags": null }, - "/notes/setup": { + "/configuration/setup": { "title": "Setup", "content": "\n## Making your own Quartz\nSetting up Quartz requires a basic understanding of `git`. If you are unfamiliar, [this resource](https://resources.nwplus.io/2-beginner/how-to-git-github.html) is a great place to start!\n\n### Forking\n\u003e A fork is a copy of a repository. Forking a repository allows you to freely experiment with changes without affecting the original project.\n\nNavigate to the GitHub repository for the Quartz project:\n\n📁 [Quartz Repository](https://github.com/jackyzha0/quartz)\n\nThen, Fork the repository into your own GitHub account. If you don't have an account, you can make on for free [here](https://github.com/join). More details about forking a repo can be found on [GitHub's documentation](https://docs.github.com/en/get-started/quickstart/fork-a-repo).\n\n### Cloning\nAfter you've made a fork of the repository, you need to download the files locally onto your machine. Ensure you have `git`, then type the following command replacing `YOUR-USERNAME` with your GitHub username.\n\n```shell\ngit clone https://github.com/YOUR-USERNAME/quartz\n```\n\n## Editing\nGreat! Now you have everything you need to start editing and growing your digital garden. If you're ready to start writing content already, check out the recommended flow for editing notes in Quartz.\n\n\u003e ✏️ Step 2: [Editing Notes in Quartz](notes/editing.md)\n\nHaving problems? Checkout our [FAQ and Troubleshooting guide](notes/troubleshooting.md).\n", "lastmodified": "2022-12-31T02:53:43.348377376Z", "tags": null }, - "/notes/showcase": { - "title": "Showcase", - "content": "\nWant to see what Quartz can do? Here are some cool community gardens :)\n\n- [Quartz Documentation (this site!)](https://quartz.jzhao.xyz/)\n- [Jacky Zhao's Garden](https://jzhao.xyz/)\n- [Scaling Synthesis - A hypertext research notebook](https://scalingsynthesis.com/)\n- [AWAGMI Intern Notes](https://notes.awagmi.xyz/)\n- [Shihyu's PKM](https://shihyuho.github.io/pkm/)\n- [Chloe's Garden](https://garden.chloeabrasada.online/)\n- [SlRvb's Site](https://slrvb.github.io/Site/)\n- [Course notes for Information Technology Advanced Theory](https://a2itnotes.github.io/quartz/)\n- [Brandon Boswell's Garden](https://brandonkboswell.com)\n- [Siyang's Courtyard](https://siyangsun.github.io/courtyard/)\n- [Data Dictionary 🧠](https://glossary.airbyte.com/)\n- [sspaeti.com's Second Brain](https://brain.sspaeti.com/)\n- [oldwinterの数字花园](https://garden.oldwinter.top/)\n- [SethMB Work](https://sethmb.xyz/)\n- [Abhijeet's Math Wiki](https://abhmul.github.io/quartz/Math-Wiki/)\n\nIf you want to see your own on here, submit a [Pull Request adding yourself to this file](https://github.com/jackyzha0/quartz/blob/hugo/content/notes/showcase.md)!\n", - "lastmodified": "2022-12-31T02:53:43.348377376Z", - "tags": null - }, - "/notes/troubleshooting": { + "/configuration/troubleshooting": { "title": "Troubleshooting and FAQ", "content": "\nStill having trouble? Here are a list of common questions and problems people encounter when installing Quartz.\n\nWhile you're here, join our [Discord](https://discord.gg/cRFFHYye7t) :)\n\n### Does Quartz have Latex support?\nYes! See [CJK + Latex Support (测试)](notes/CJK%20+%20Latex%20Support%20(测试).md) for a brief demo.\n\n### Can I use \\\u003cObsidian Plugin\\\u003e in Quartz?\nUnless it produces direct Markdown output in the file, no. There currently is no way to bundle plugin code with Quartz.\n\nThe easiest way would be to add your own HTML partial that supports the functionality you are looking for.\n\n### My GitHub pages is just showing the README and not Quartz\nMake sure you set the source to deploy from `master` (and not `hugo`) using `/ (root)`! See more in the [hosting](/notes/hosting) guide\n\n### Some of my pages have 'January 1, 0001' as the last modified date\nThis is a problem caused by `git` treating files as case-insensitive by default and some of your posts probably have capitalized file names. You can turn this off in your Quartz by running this command.\n\n```shell\n# in the root of your Quartz (same folder as config.toml)\ngit config core.ignorecase true\n\n# or globally (not recommended)\ngit config --global core.ignorecase true\n```\n\n### Can I publish only a subset of my pages?\nYes! Quartz makes selective publishing really easy. Heres a guide on [excluding pages from being published](notes/ignore%20notes.md).\n\n### Can I host this myself and not on GitHub Pages?\nYes! All built files can be found under `/public` in the `master` branch. More details under [hosting](notes/hosting.md).\n\n### `command not found: hugo-obsidian`\nMake sure you set your `GOPATH` correctly! This will allow your terminal to correctly recognize `hugo-obsidian` as an executable.\n\n```shell\n# Add the following 2 lines to your ~/.bash_profile\nexport GOPATH=/Users/$USER/go\nexport PATH=$GOPATH/bin:$PATH\n\n# In your current terminal, to reload the session\nsource ~/.bash_profile\n```\n\n### How come my notes aren't being rendered?\nYou probably forgot to include front matter in your Markdown files. You can either setup [Obsidian](notes/obsidian.md) to do this for you or you need to manually define it. More details in [the 'how to edit' guide](notes/editing.md).\n\n### My custom domain isn't working!\nWalk through the steps in [the hosting guide](notes/hosting.md) again. Make sure you wait 30 min to 1 hour for changes to take effect.\n\n### How do I setup Google Analytics?\nYou can edit it in `config.toml` and either use a V3 (UA-) or V4 (G-) tag.\n\n### How do I change the content on the home page?\nTo edit the main home page, open `/content/_index.md`.\n\n### How do I change the colours?\nYou can change the theme by editing `assets/custom.scss`. More details on customization and themeing can be found in the [customization guide](notes/config.md).\n\n### How do I add images?\nYou can put images anywhere in the `/content` folder.\n\n```markdown\nExample image (source is in content/notes/images/example.png)\n![Example Image](/content/notes/images/example.png)\n```\n\n### My Interactive Graph and Backlinks aren't up to date\nBy default, the `linkIndex.json` (which Quartz needs to generate the Interactive Graph and Backlinks) are not regenerated locally. To set that up, see the guide on [local editing](notes/editing.md)\n\n### Can I use React/Vue/some other framework?\nNot out of the box. You could probably make it work by editing `/layouts/_default/single.html` but that's not what Quartz is designed to work with. 99% of things you are trying to do with those frameworks you can accomplish perfectly fine using just vanilla HTML/CSS/JS.\n\n## Still Stuck?\nQuartz isn't perfect! If you're still having troubles, file an issue in the GitHub repo with as much information as you can reasonably provide. Alternatively, you can message me on [Twitter](https://twitter.com/_jzhao) and I'll try to get back to you as soon as I can.\n\n🐛 [Submit an Issue](https://github.com/jackyzha0/quartz/issues)", "lastmodified": "2022-12-31T02:53:43.348377376Z", "tags": null }, - "/notes/updating": { + "/configuration/updating": { "title": "Updating", "content": "\nHaven't updated Quartz in a while and want all the cool new optimizations? On Unix/Mac systems you can run the following command for a one-line update! This command will show you a log summary of all commits since you last updated, press `q` to acknowledge this. Then, it will show you each change in turn and press `y` to accept the patch or `n` to reject it. Usually you should press `y` for most of these unless it conflicts with existing changes you've made! \n\n```shell\nmake update\n```\n\nOr, if you don't want the interactive parts and just want to force update your local garden (this assumed that you are okay with some of your personalizations been overriden!)\n\n```shell\nmake update-force\n```\n\nOr, manually checkout the changes yourself.\n\n\u003e [!warning] Warning!\n\u003e\n\u003e If you customized the files in `data/`, or anything inside `layouts/`, your customization may be overwritten!\n\u003e Make sure you have a copy of these changes if you don't want to lose them.\n\n\n```shell\n# add Quartz as a remote host\ngit remote add upstream git@github.com:jackyzha0/quartz.git\n\n# index and fetch changes\ngit fetch upstream\ngit checkout -p upstream/hugo -- layouts .github Makefile assets/js assets/styles/base.scss assets/styles/darkmode.scss config.toml data \n```\n", "lastmodified": "2022-12-31T02:53:43.348377376Z", "tags": null }, - "/posts/": { - "title": "Blog", + "/cs61b/": { + "title": "Welcome to CS61B!", + "content": "\n# Welcome\n\n## Welcome to 64bitpanda's CS61B Guide!\n\n(If you are looking at this in github, go to [cs61b.bencuan.me](https://cs61b.bencuan.me) for a much better experience!)\n\nThis is a **non-comprehensive** guide to data structures written with an intention to supplement learning and reviewing of Berkeley's [CS61B](https://inst.eecs.berkeley.edu/\\~cs61b) material. Main topics include:\n\n* Object oriented programming basics\n* Abstract data types\n* Asymptotics and runtime analysis\n* Sorting algorithms\n* Search algorithms\n* And some more miscellaneous topics thrown in!\n\nThis guide is written to be as easy to follow and digestible as possible😀I've included lots of diagrams, practice problems, and more intuitive explanations instead of the more straightforward approach most textbooks use. **This isn't a replacement for lectures and other course content.** You probably need to look at those first, and come here if something isn't sticking!\n\n### The 61B Concept Map\n\n![](\u003cimg/assets/image (6).png\u003e)\n\n\n\n## Who is this for?\n\nMostly me; making unnecessarily detailed guides is my goto method of making sure I understand everything😁But you are welcome to use it as well for reviewing for 61B exams, touching up on data structures knowledge, or whatever you want!\n\n**Basic knowledge gained from** [**CS61A**](https://cs61a.org/) **or equivalent is assumed.** [Click here](https://cs61a.bencuan.me) for my notes for that!\n\n## How to use this guide\n\nAgain, I will emphasize that this **isn't a textbook.** While I try to be as comprehensive as possible, I'm sure I missed plenty of important concepts or assume you know others. I don't have an army of peer reviewers and guinea pigs to test-read the thing, so it's also not guaranteed that everything is 100% accurate. Please [open an issue](https://github.com/64bitpandas/cs61b-notes/issues) if you think something's wrong!\n\n{% hint style=\"warning\" %}\nFor more difficult topics, I'll put a warning like this at the top of the page with links to prerequisites or supporting topics so that you won't feel completely lost 😉\n{% endhint %}\n\nThere are also plenty of practice problems to try out! Here's an non-exhaustive list of pages with those if you are mostly interested in them and not the conceptual content.\n\n* [Access Control](oop/access-control.md#practice)\n* [Dynamic Method Selection](oop/dynamic-method-selection.md)\n* [Generic Types](oop/generics.md#generic-subtypes)\n* [Asymptotics Practice](asymptotics/asymptotics-practice.md)\n\n\n\n## How to contribute\n\nFork the [GitHub repository](https://github.com/64bitpandas/cs61b-notes) and create a pull request. All contributions are welcome! Pages are formatted in [Markdown syntax](https://docsimg.com/editing-content/markdown). Please **edit existing pages only** unless you have [created an issue](https://github.com/64bitpandas/cs61b-notes/issues) and I have gotten back to you about making a new page. Thanks 😄\n\nThe pages that could be most improved (in no particular order) are [Union Find (Disjoint Sets)](abstract-data-types/union-find-disjoint-sets.md), [Stacks and Queues](abstract-data-types/collections/stacks-and-queues.md), [Linked Lists](abstract-data-types/collections/linked-lists.md), [Sets](abstract-data-types/collections/sets.md), [Sorting](sorting/sorting-basics.md), [Searching](algorithms/searching/), [Binary Search](algorithms/searching/binary-search.md), [Shortest Paths](algorithms/shortest-paths/), and [Exceptions](misc-topics/exceptions.md). Feel free to add whatever content you like (explanations, examples, practice problems, memes...) to these!\n\nAdditionally, there are plenty of topics (Regex, Testing, Files/Scanners, Ranges, GUI just to name a few) that aren't currently covered in this guide. If you want to add one of these topics, please create an issue first but it will almost certainly be approved.\n\n### Credits\n\n* [Ben Cuan (64bitpandas)](https://github.com/64bitpandas)\n* [Arin Chang](https://github.com/arinchang)\n\n\n\n![[classes/cs61b/SUMMARY]]", + "lastmodified": "2023-01-05T06:38:49.27788034Z", + "tags": null + }, + "/cs61b/SUMMARY": { + "title": "CS61B", + "content": "\n# Table of contents\n\n* [Welcome](CS61B%20Index.md)\n\n## Object Oriented Programming \u003ca id=\"oop\"\u003e\u003c/a\u003e\n\n* [Inheritance](oop/inheritance.md)\n* [Access Control](oop/access-control.md)\n* [Dynamic Method Selection](oop/dynamic-method-selection.md)\n* [Java Objects](oop/objects.md)\n* [Generic Types](oop/generics.md)\n\n## Asymptotics\n\n* [Asymptotic Analysis Basics](asymptotics/asymptotics.md)\n* [Amortization](asymptotics/amortization.md)\n* [Asymptotics Practice](asymptotics/asymptotics-practice.md)\n\n## Abstract Data Types\n\n* [Collections](abstract-data-types/collections/README.md)\n * [Arrays](abstract-data-types/collections/arrays.md)\n * [Linked Lists](abstract-data-types/collections/linked-lists.md)\n * [Sets](abstract-data-types/collections/sets.md)\n * [Stacks and Queues](abstract-data-types/collections/stacks-and-queues.md)\n* [Binary Trees](abstract-data-types/binary-trees/README.md)\n * [Heaps](abstract-data-types/binary-trees/heaps.md)\n * [Balanced BSTs](abstract-data-types/binary-trees/balanced-search-structures.md)\n * [Tries](abstract-data-types/binary-trees/tries.md)\n* [Graphs](abstract-data-types/graphs.md)\n* [Hashing and Hash Tables](abstract-data-types/hashing.md)\n* [Union Find \\(Disjoint Sets\\)](abstract-data-types/union-find-disjoint-sets.md)\n* [Comparables and Comparators](abstract-data-types/comparables-and-comparators.md)\n\n## Sorting\n\n* [Sorting](sorting/sorting-basics.md)\n\n## Algorithms\n\n* [Minimax Algorithm](algorithms/minimax.md)\n* [Searching](algorithms/searching/README.md)\n * [Binary Search](algorithms/searching/binary-search.md)\n * [Depth First Search \\(DFS\\)](algorithms/searching/depth-first-search-dfs.md)\n * [Breadth First Search \\(BFS\\)](algorithms/searching/breadth-first-search-bfs.md)\n* [Shortest Paths](algorithms/shortest-paths/README.md)\n * [Dijkstra's Algorithm](algorithms/shortest-paths/dijkstras-algorithm.md)\n * [A\\* Search](algorithms/shortest-paths/a-search.md)\n* [Minimum Spanning Trees](algorithms/minimum-spanning-trees/README.md)\n * [Prim's Algorithm](algorithms/minimum-spanning-trees/prims-algorithm.md)\n * [Kruskal's Algorithm](algorithms/minimum-spanning-trees/kruskals-algorithm.md)\n\n## Misc Topics\n\n* [Modular Arithmetic and Bit Manipulation](misc-topics/modular-arithmetic.md)\n* [Exceptions](misc-topics/exceptions.md)\n* [More Resources](misc-topics/more-resources.md)\n\n", + "lastmodified": "2023-01-03T02:02:19.144391466Z", + "tags": null + }, + "/cs61b/abstract-data-types/binary-trees/README": { + "title": "", + "content": "# Binary Trees\n\n{% hint style=\"success\" %}\n\"The most important concept in computer science\" - Josh Hug\n{% endhint %}\n\n## Humble Origins\n\nLinked lists are great, but we can do better! Let's try **rearranging the pointers** in an interesting way.\n\nInstead of starting at one end of the list, let's set our first pointer at the **middle** of the list!\n\n![](\u003c../../img/assets/image (69).png\u003e)\n\nNow, let's make new pointers going to the **center** of each **sublist** on the left and right of the center.\n\n![](\u003c../../img/assets/image (70).png\u003e)\n\nLet's do it again!\n\n![](\u003c../../img/assets/image (71).png\u003e)\n\nWould ya look at that, we've got a **tree**! 🌲\n\n![🌲🌲🌲🌲🌲](\u003c../../img/assets/image (73).png\u003e)\n\n## Types of Trees\n\nRight now, we can determine some properties that all trees have.\n\n* All trees have a **root node**.\n* All nodes can point to **child nodes.** Or, if they don't have any children, they are **leaves.**\n\nWe can add more and more constraints to our tree to make them more useful!\n\nFirst, let's add the constraint that **node can only have 2 or fewer children** to create a **binary tree.**\n\nThen, let's **ensure our tree is sorted** to create a **binary search tree.** A tree is sorted if it has these properties:\n\n* Every value in the **left subtree** of a node is **less than** the node's value.\n* Every value in the **right subtree** of a node is **greater than** the node's value.\n* Values are **transitive** - there are **no duplicate values**.\n* The tree is **complete** - it is possible to **compare any two values** in the tree and say that one is **either less than or greater than the other.**\n* The tree is **antisymmetric** - If `p \u003c q` is true and `q \u003c r` is also true, then it must follow that `p \u003c r`.\n\n## Tree Operations\n\nThere are **three important operations** that trees should support: **find, insert, and delete.**\n\n### **Find**\n\nFinding a value in a tree uses Binary Search. Click the link below to read up on it!\n\n{% content-ref url=\"../../algorithms/searching/binary-search.md\" %}\n[binary-search.md](../../algorithms/searching/binary-search.md)\n{% endcontent-ref %}\n\n### Insert\n\nThe insert algorithm is **very similar to binary search.** Here are the steps to take:\n\n* Search for the item. **If it's found, then do nothing** since the value is already in the tree.\n* If it's not found (search would return null in this case), then create a node and put it where it should be found. If using recursion, this last step is already done- all we need to do is return a new node!\n\nHere's the algorithm:\n\n```java\npublic BST insert(BST T, Key sk) {\n if (T == null) {\n // Create new leaf with given key. Different from search\n return new BST(sk, null, null); \n }\n if (sk.equals(T.key)) {\n return T;\n } else if (sk \u003c T.key) {\n T.left = find(T.left, sk); // Different from search\n } else {\n T.right = find(T.right, sk); // Different from search\n }\n}\n```\n\n### Delete\n\nThis one's a bit trickier because we need to make sure that the new tree still **preserves the binary search tree structure.** That means that we might have to shuffle around nodes after the deletion. There are **three cases:**\n\nA) The node to delete is a **leaf**. This is an easy case- just remove that node and you're done!\n\n![Deleting a leaf.](\u003c../../img/assets/image (64).png\u003e)\n\nB) The node to delete has **one child.** In this case, **swap** the node with its child, then **delete the node.**\n\n![Deleting a node with one child.](\u003c../../img/assets/image (65).png\u003e)\n\nC) The node to delete has **two children.** This one's trickier, because we still need to preserve the tree structure! In this case, we have to **traverse the node's children** to find the **next biggest value** and swap that up to replace the old node.\n\n![Deleting a node with two children.](\u003c../../img/assets/image (66).png\u003e)\n\n## Asymptotic Analysis\n\nA binary tree can be **bushy** or **spindly.** These two cases have dramatically different performances!\n\n**Bushy** trees are the **best case.** A tree is bushy if **every parent has exactly 2 children.**\n\nA bushy tree is guaranteed to have a height of $\\Theta(\\log(n))$ which means that the runtimes for adding and searching will also be $\\Theta(\\log(n))$ .\n\n**Spindly** trees are the **worst case.** A tree is spindly if **every parent has exactly 1 child.** This makes the tree essentially just a linked list!\n\nA spindly tree has a height of $\\Theta(n)$ which means that the runtimes for adding and searching will also be $\\Theta(n)$ .\n\n![](\u003c../../img/assets/image (67).png\u003e)\n\nIn [Balanced BSTs](balanced-search-structures.md), we will explore ways of guaranteeing that a tree is bushy!\n\n## Limits of Trees\n\nWhile trees are extremely versatile and fantastic for a variety of applications, trees have some limitations that make it difficult to use in some situations.\n\n* **All items in a tree need to be comparable.** We can't construct a binary tree out of categorical data, like models of cars, for example.\n* **The data must be hierarchical.** If data can be traversed through in multiple ways, or forms loops, [Graphs](../graphs.md) are probably better.\n* **The best case runtime is** $\\Theta(\\log(n))$ . This might seem good, but other data structures like [Tries](tries.md) and [Hash Tables](../hashing.md) can be as good as **** $\\Theta(1)$ !\n\n## Tree Traversals\n\nCheck out these pages for information on how to go through each element of a tree!\n\n{% content-ref url=\"../../algorithms/searching/depth-first-search-dfs.md\" %}\n[depth-first-search-dfs.md](../../algorithms/searching/depth-first-search-dfs.md)\n{% endcontent-ref %}\n\n{% content-ref url=\"../../algorithms/searching/breadth-first-search-bfs.md\" %}\n[breadth-first-search-bfs.md](../../algorithms/searching/breadth-first-search-bfs.md)\n{% endcontent-ref %}\n\n", + "lastmodified": "2023-01-03T01:48:32.700428829Z", + "tags": null + }, + "/cs61b/abstract-data-types/binary-trees/balanced-search-structures": { + "title": "", + "content": "# Balanced BSTs\n\n{% hint style=\"warning\" %}\nPlease read [Binary Trees](./) before continuing!\n{% endhint %}\n\n**Balanced Binary Search Trees** are an even more specific subcategory of binary trees that have an important property: **they are always bushy.**\n\n## B Trees (2-4 Trees)\n\n**The basic idea:** Nodes can hold multiple values now! When nodes have too many values, we will split it.\n\nA **2-4 tree** is named such because each parent can have **2 to 4 children.** Another constraint we will put on is a **limit on the** **number of items allowed in a single node**, so that we can guarantee that searching a single node will always be $\\Theta(n).$\n\n### **Adding Values to a B-Tree**\n\nAdding values to a B Tree can be a bit tricky because we need to make sure all the properties are still followed. Here are some example scenarios:\n\nIf a node already has 2 or more children, place the new value in one of its existing children.\n\n![](\u003c../../img/assets/image (81).png\u003e)\n\nIf a node is full (reaches the limit), we must **split the node** by **moving one value up to the parent** and **creating another child node**. Here, we'll use a limit of **3**.\n\n![](\u003c../../img/assets/image (82).png\u003e)\n\n### Properties of B Trees\n\n* Searching in a single node is **constant runtime** since the limit is a constant.\n* All leaves must be the **same distance** from the root.\n* A non-leaf node with **k** items must have **k+1** children.\n* The height of a B tree is guaranteed to be $\\Theta(\\log(n))$ because it is bushy.\n\n## Red-Black Trees and Tree Rotation\n\n**The basic idea:** Let's try to represent B trees in a **binary tree format.** That means that every parent can only have 2 children! In order to do this, we'll **add an extra color property** to each node.\n\n**Black nodes** are just like any normal binary tree node, but **Red nodes** represent the nodes in B Trees that have **more than one value.** For example, let's convert the B Tree we were working with before into a RB Tree.\n\n![](\u003c../../img/assets/image (83).png\u003e)\n\nIn order to make our lives easier, we'll restrict our Red Black trees into **left leaning red black trees** which can **only have red nodes on the left.**\n\n### **Tree Rotation**\n\nIn order to ensure that adding new nodes won't break the Red Black Tree structure, we will use a concept called **tree rotation** which swaps around nodes. There are two rotations, a **left rotation** and a **right rotation,** which move a child node up to replace its parent. For example, a **left rotation** moves the **right node up and left** to replace the parent.\n\nA \"left rotation on 7\" looks like this:\n\n![](\u003c../../img/assets/image (84).png\u003e)\n\nNotice that the **8** gets moved to be a **right child** of **7** after the rotation! This is necessary to preserve the binary tree structure.\n\nA \"right rotation on 7\" looks like this:\n\n![](\u003c../../img/assets/image (85).png\u003e)\n\nHere, the **6** gets moved to be a **left child** of **7.**\n\nIf you want to see how these rotations can be implemented into the `insert` algorithm, [try the homework](https://inst.eecs.berkeley.edu/\\~cs61b/sp20/materials/hw/hw8/index.html) on implementing a LLRB Tree! Below is a brief outline on how insert works:\n\n* **Always add values to a leaf node as a red node first.** Follow normal sorted binary tree rules.\n* If the link is leaning right, rotate the tree to make it left leaning.\n* If a node already has a red link to the left, temporarily add it to the right also as a red link.\n * Then, flip the color of all links connected to the node (if previously black, turn red; if previously red, turn black)\n * Might need to fix right-leaning red nodes that are created as a result\n* If a node has red links to both parent and child, rotate it such that it becomes the above case, and then handle that case like you did before.\n\n### Properties of Red Black Trees\n\nLike B Trees, Red Black Trees have some important properties that allow them to be easily distinguishable.\n\n* Red Black trees have a **one-to-one correspondence** with B trees. That means for every Red Black tree, there is exactly one B Tree that represents the same connections. This also means that a Red Black Tree will have the same runtimes as their corresponding B Trees. (Take a linear algebra course to learn more about isomorphisms 🙂 )\n* **Every node must have the same number of black nodes in between itself and the root.** This might be a bit surprising at first, but remember that their corresponding B Tree is always bushy, and red links mean a multi-value node in a B Tree.\n", + "lastmodified": "2023-01-03T01:48:32.700428829Z", + "tags": null + }, + "/cs61b/abstract-data-types/binary-trees/heaps": { + "title": "", + "content": "# Heaps\n\n## What are Heaps?\n\nA heap is a **specific order of storing data,** often in a list. Heaps are very similar to binary trees, but have some differences:\n\n* Unlike trees, heaps **only care about the root node.** Usually, the root node is either the **largest** or **smallest** value in the heap (corresponding with max-heaps and min-heaps), and we don't care too much about the rest.\n* Every element in the heap must be **larger than all its children** (in a max-heap) or **smaller than all its children** (in a min-heap). This is known as the **heap property.**\n\nWhen stored in a list, there is an **important rule** to figure out how to identify parent nodes and their children: **a node's parent has an index equal to half of that node's index.** More specifically, `parentIndex = nodeIndex / 2` where `/` has floor-division properties.\n\n![Converting a heapified list into a min-heap diagram.](\u003c../../img/assets/image (60).png\u003e)\n\n## The Heapify Algorithm\n\nThe most important heap algorithm is **heapify**, which converts any non-heap list into a heap. This algorithm is vital to most heap functions like insert or remove, since these functions often break the heap structure before fixing it with heapify.\n\n**Here's how it works:**\\\n****(This example is an excerpt from my [Sorting Guide](https://docs.google.com/document/d/1dUfzdh5V3okrwFbB9o0PgtEBaLHyCqJFwpQWyQ53IeU/edit). The example provided is a max-heap \\[5,6,2,4,1].)\n\nStart with the element in the middle of the array (which is the root of the heap).\n\n![](\u003c../../img/assets/image (61).png\u003e)\n\nIf the root is smaller than either of its children (larger for a min-heap), swap it with its largest child (smallest for a max-heap).\n\n![](\u003c../../img/assets/image (62).png\u003e)\n\n\n\nIf the root was swapped, recursively call heapify on the new position. Otherwise, stop recursion.\n\nAfter heapify is complete, it should look like this:\n\n![](\u003c../../img/assets/image (63).png\u003e)\n\n## Practical Applications\n\n[Lab 9](https://inst.eecs.berkeley.edu/\\~cs61b/sp20/materials/lab/lab9/index.html) is a fantastic resource for practicing heap implementations and working with the algorithms that are needed to work with heaps (like heapify, insert, remove). Since this lab goes into plenty of detail about how each of these algorithms work, I won't explain them too much here.\n\nHeap sort relies on the heap structure to provide consistent nlogn sorting! I have more information about this on page 11 in my [sorting guide](https://docs.google.com/document/d/1dUfzdh5V3okrwFbB9o0PgtEBaLHyCqJFwpQWyQ53IeU/edit).\n", + "lastmodified": "2023-01-03T01:48:32.700428829Z", + "tags": null + }, + "/cs61b/abstract-data-types/binary-trees/tries": { + "title": "", + "content": "# Tries\n\n## Main Ideas\n\nA **trie** is a specific implementation of a set and is short for **retrieval tree.**\n\nIt only works on sets with a **finite alphabet**, like digits or ASCII characters, for example. The idea is that each node can act like an **array containing all characters in the alphabet** and we can just access the branches super fast by indexing into them!\n\nTries are fantastic for searching to see if a word is contained in a set. Here's an example:\n\n![This trie contains the words 'batcat', 'batman', and 'banana'.](\u003c../../img/assets/image (74).png\u003e)\n\nThis is great because it makes the `add()` and `contains()` functions run in $\\Theta(1)$ time! Additionally, it makes special string operations like prefix matching or autocomplete very efficient.\n\nWe can improve this data structure a lot- for instance, we can condense the leaves to reduce the number of nodes like this:\n\n![](\u003c../../img/assets/image (75).png\u003e)\n\nI won't go into too much detail on how to optimize it further, or how to implement the actual functions efficiently, but hopefully you'll have a good sense of how to do it yourself after learning about concepts like [Hashing and Hash Tables](../hashing.md) or [Sets](../collections/sets.md) etc.\n", + "lastmodified": "2023-01-03T01:48:32.700428829Z", + "tags": null + }, + "/cs61b/abstract-data-types/collections/README": { + "title": "", + "content": "# Collections\n\n![An overview of all the Collections in Java.](\u003c../../img/assets/image (3).png\u003e)\n\n**Collection** is a Java interface for common abstract data types that store multiple items in them.\n\n## Sub-Interfaces\n\n* **Lists** are indexed sequences with duplication. The two most common types are [**ArrayLists**](arrays.md#array-lists) **** and [**Linked Lists**](linked-lists.md)**.**\n* ****[**Sets**](sets.md) **** are non-indexed sequences with no duplication. (That is, every value in a set is unique.)\n* **Maps** are key-value pairs. See [Hashing and Hash Tables](../hashing.md) for a description on one common map implementation, the HashMap. All keys in a map must be unique, but values can be duplicated.\n* ****[**Stacks and Queues**](stacks-and-queues.md) **** are two ordered collections that have two core behaviors:\n * push(T x): puts x on the top.\n * pop(): Removes the first item. (See the stacks and queues page for more information.)\n\n## Common Functions\n\n* **Membership tests** `contains()` and `containsAll()` that can determine whether or not an element is in the collection.\n* `size()` to get the number of items in the collection.\n* `isEmpty()` returns true if there is nothing in the collection.\n* `iterator()` returns an Iterator object to go through all the values in the collection.\n* `toArray()` converts the collection to a standard Java array.\n* **Optional** functions that aren't implemented in the interface: `add, addAll, clear, remove, removeAll, retainAll (intersection)`\n * Throws `UnsupportedOperationException` if not implemented.\n", + "lastmodified": "2023-01-03T01:48:32.700428829Z", + "tags": null + }, + "/cs61b/abstract-data-types/collections/arrays": { + "title": "", + "content": "# Arrays\n\n{% hint style=\"info\" %}\nThis page assumes prior knowledge of Python lists from CS61A or equivalent.\n{% endhint %}\n\nArrays are a very popular data structure that stores an indexed list of data. \\\n\n\n![An artistic interpretation of a new int\\[5\\] {6, 1, 2, 3, 99};](\u003c../../img/assets/image (37).png\u003e)\n\n## Properties\n\n* **Fixed length:** after instantiation, the length of an array cannot be changed.\n* Every value in array is the **same type** and holds the **same amount of bits** in memory.\n* **Zero-indexed.** That means `arr[0]` returns the first value, and `arr[arr.length]` is out of bounds.\n* **No methods.** Helper methods from other libraries (like `System.arraycopy`) need to be used to manipulate arrays.\n* **Retrieval is independent of size** and takes constant time regardless of how big arrays are.\n\n## Using Arrays in Java\n\n**Instantiation:**\n\n* `int[] a = {1, 2, 3, 4, 5};` assigns values.\n* `int b = new int[3];` creates array of provided length populated with default values.\n\n**Copying**\n\n* Simply assigning `int[] c = b` will copy the **pointer** to array b! Not the values! See [Java Objects](../../oop/objects.md) for a discussion on why this is significant.\n* Use `System.arraycopy(source, start, target, startTarget, amountToCopy)` to **shallow copy** the values (or pointers) in the array. That is, if an array is holding **reference types,** only the pointers will be copied and not the actual values of the reference objects being held.\n* `System.arraycopy(b, 0, x, 3, 2)` is equivalent to `x[3:5] = b[0:2]` in Python.\n\n**Multidimensional Arrays**\n\n* `int[][] 2d = new int[4][4];`or `int[][] 2d = new int[][] {{1}, {2, 3}, {4, 5, 6}};`will create **arrays inside of an array.** This is useful for storing matrices, coordinate maps, or any other multidimensional data!\n\n**Generic Arrays**\n\n* Arrays of generic objects are NOT allowed! Use ArrayLists instead.\n* Or, this workaround can be used:`Type[] items = (Type[]) new Object[length]`\n\n## Array Lists\n\nJava has another built-in type that uses an array under the hood, which is the `ArrayList`. Here's how ArrayLists are different from normal arrays:\n\n* ArrayLists can resize arbitrarily. (They use something similar to the array case study in the [Amortization](../../asymptotics/amortization.md#what-if-we-doubled-the-size-instead-of-adding-one) page.\n* ArrayLists use [Generic Types](../../oop/generics.md) and therefore do not support primitive types like `int`.\n* ArrayLists have all behaviors expected from the [Collections](./) interface.\n", + "lastmodified": "2023-01-03T01:48:32.700428829Z", + "tags": null + }, + "/cs61b/abstract-data-types/collections/linked-lists": { + "title": "", + "content": "# Linked Lists\n\n{% hint style=\"info\" %}\nThis page assumes prior knowledge of linked lists from CS61A or equivalent. I'll assume you have already worked with basic singly linked lists before.\n{% endhint %}\n\nThe linked list is an extremely common recursive data structure that allows storage and access of an arbitrary amount of data.\n\n## Feature List of an Effective Linked List\n\n1. **Rebranding**- represents Node as an individual object rather than having one monolithic List type.\n2. **Bureacracy:** Create an abstraction barrier so that users do not need to know how methods or Nodes work, only how to call them.\n3. **Access Control:** Data cannot be accessed directly to prevent dangerous behavior; only the provided methods are used.\n4. **Nested Class:** Nodes are nested within the List object since other classes do not need it.\n5. **Caching:** The size of the list is incremented every time a node is added, so running size() is O(1) and traversal is not needed.\n6. **Generalizing:** A **sentinel node** represents an empty list and remains the first node of the list. When getFirst() is called, the second node is actually returned (since the first node is always the sentinel).\n7. **Doubly Linked:** Nodes have both first and last pointers for even faster traversal.\n8. **Circular list:** Sentinel last pointer points to the last value in the node, allowing for fast removeLast().\n\n![An illustration of an effective linked list.](\u003c../../img/assets/image (36).png\u003e)\n\n## Method List\n\n| Method | Description | Optimal Runtime |\n| -------------------------------------------------------------------- | ------------------------------------------------ | --------------- |\n| \u003cp\u003e\u003ccode\u003eaddFirst(T x)\u003c/code\u003e\u003c/p\u003e\u003cp\u003e\u003ccode\u003eaddLast(T x)\u003c/code\u003e\u003c/p\u003e | Adds a node to the front/back of the list. | $\\Theta(1)$ |\n| \u003cp\u003e\u003ccode\u003egetFirst()\u003c/code\u003e\u003c/p\u003e\u003cp\u003e\u003ccode\u003egetLast()\u003c/code\u003e\u003c/p\u003e | Gets the node at the front/back of the list. | $\\Theta(1)$ |\n| \u003cp\u003e\u003ccode\u003eremoveFirst()\u003c/code\u003e\u003c/p\u003e\u003cp\u003e\u003ccode\u003eremoveLast()\u003c/code\u003e\u003c/p\u003e | Removes the node at the front/back of the list. | $\\Theta(1)$ |\n| `size()` | Returns the number of nodes in the list. | $\\Theta(1)$ |\n| `contains(T x)` | Returns true if the list contains element `x`. | $\\Theta(n)$ |\n| \u003cp\u003e\u003ccode\u003eadd(T x, int pos)\u003c/code\u003e\u003c/p\u003e\u003cp\u003e\u003ccode\u003eremove(T x)\u003c/code\u003e\u003c/p\u003e | Adds/remove an element at an arbitrary location. | $\\Theta(n)$ |\n\n## Limitation: Arbitrary Retrieval\n\nYou may have noticed in the chart above that it takes $\\Theta(n)$ time to retrieve arbitrary values from the list. This will get really slow if the list is large! If arbitrary values need to be accessed frequently, [Arrays](arrays.md) are much better.\n\n## The Java List Interface\n\nJava has a built-in `LinkedList` class so you don't have to implement it yourself! Read up on the [official docs](https://docs.oracle.com/javase/8/docs/api/java/util/LinkedList.html/) to learn more about the specific methods and behaviors provided.\n\n", + "lastmodified": "2023-01-03T01:48:32.704428808Z", + "tags": null + }, + "/cs61b/abstract-data-types/collections/sets": { + "title": "", + "content": "# Sets\n\n{% hint style=\"warning\" %}\nThis page is from my original notes and is not up to the latest quality standards. Read with care or [help make it better!](https://github.com/64bitpandas/cs61b-notes/pulls)\n{% endhint %}\n\n## Basics\n\nA Set stores a collection of values with **no duplicates.** Sets have no inherent order, so you can't rely on expecting any value to come before any other value when iterating through them.\n\nSome set functions include:\n\n* `add(T x)`\n* `contains(T x)`\n* `size()`\n\n## ArraySet\n\nAn ArraySet is an array-based solution to a set implementation.\n\n* Objects get added to an array that gets [resized](../../asymptotics/amortization.md) when it's too full.\n* In order to allow for iteration, we can use one of two methods:\n * One method is to use **iterators** which work very similarly to Python iterators:\n\n ```java\n Iterator\u003cInteger\u003e seer = set.iterator();\n while (seer.hasNext()) {\n System.out.println(seer.next());\n }\n ```\n * Another method is to implement the `Iterator` and `Iterable` interface.\n * Iterator must implement `hasNext()` and `next()` methods\n * Requires generic type\n * Iterable must implement `iterator()` method which returns the Iterable object\n * Allows usage of for/foreach loops\n", + "lastmodified": "2023-01-03T01:48:32.704428808Z", + "tags": null + }, + "/cs61b/abstract-data-types/collections/stacks-and-queues": { + "title": "", + "content": "# Stacks and Queues\n\nStacks and queues are two very common data structures used for a variety of applications from [CPU processes](https://www.tutorialspoint.com/operating\\_system/os\\_processes.htm) to [finding shortest paths using Dijkstra's Algorithm](../../algorithms/shortest-paths/dijkstras-algorithm.md). Fundamentally, they are very similar in structure and **only differ by the order in which items are popped from them**.\n\n## Pushing and Popping\n\n### Pushing\n\nAdding an item to a stack or queue is called **pushing**. This will either put the item on the **top** of a stack or in the **back** of a queue.\n\nYou can think of a stack like a pile of pizza boxes- the one on the top is the first one you have to take off if you need one!\n\n![](\u003c../../img/assets/image (52).png\u003e)\n\nOn the other hand, you can think of a queue like lining up for a ride at Disneyland. The first person who gets in line will get to go first, and the last person who gets in will go last. (Of course, we all know people cut and stuff- see [Priority Queues](stacks-and-queues.md#priority-queues) to see how this is better handled.)\n\n![those lines tho](\u003c../../img/assets/image (54).png\u003e)\n\n### Popping\n\nTaking an item out of a stack or queue is called **popping.**\n\nStacks are **last in, first out (LIFO).** That means the last item that you put in will be the first item that gets popped.\n\nQueues are **first in, first out (FIFO).** That means that the first item that you put in will be the first item that gets popped.\n\n## Priority Queues\n\nLet's say you bought a VIP pass and get to cut to the front of the line for your favorite Disneyland ride! Well, a normal Queue won't be able to model this behavior since it puts everything in the back by default.\n\nA priority queue will solve this design need by introducing a new **priority** **tracking system** for each item in the queue! **If an item has a lower priority number, it will get to go first.**\n\n![gotta grab those fastpasses yEEt 🎟](\u003c../../img/assets/image (53).png\u003e)\n", + "lastmodified": "2023-01-03T01:48:32.704428808Z", + "tags": null + }, + "/cs61b/abstract-data-types/comparables-and-comparators": { + "title": "", + "content": "# Comparables and Comparators\n\n## What is it?\n\nA **Comparable** is a **generic type** that allows standardized comparisons between objects.\n\nIn other words, anything that has a `compareTo()` method can be a Comparable!\n\nMany Java libraries already use Comparable without you knowing! Some of the more well-known ones are `Collection` and `String`.\n\n### CompareTo can't return anything you want!\n\nThere are some very specific properties CompareTo needs to have! Usually, we take them for granted but might forget about them when making our own.\n\n* If `x` and `y` are the **same object**, `y.compareTo(x)` must return **0.**\n* `x.compareTo(y)` must return the **negative** of `y.compareTo(x)`. (if one throws an error, the other must too!)\n* If `x` and `y` are the **same object**, `x.compareTo(z)` must **equal** `y.compareTo(z)` **for all z.**\n\n### Defining a Comparable subclass\n\n```java\npublic class MyComparable implements Comparable\u003cMyComparable\u003e {\n public int foo;\n ...\n\n /** Instance method that has nothing to do with comparable */\n public void doSomething() {\n ...\n }\n\n /** Comparable method used to compare objects of this type */\n public int compareTo(Object o) {\n MyComparable mc = (MyComparable) o;\n return ...\n }\n}\n```\n\n## **Comparators**\n\nComparators are used instead of higher order functions in order to provide a **callback** function to methods. One example of where it is used commonly is `Collections.sort`. You can pass in a comparator here to change how items are sorted- for example, you could sort `Person` objects by their `height` variable.\n\n**The interface is as follows:**\n\n```java\npublic interface Comparable\u003cT\u003e {\n int compare(T o1, T o2);\n}\n```\n\n### How is it different from Comparables???\n\nComparable is used to compare **itself** to **other objects**; a Comparator compares **two other objects but not itself.**\n\n", + "lastmodified": "2023-01-03T01:48:32.704428808Z", + "tags": null + }, + "/cs61b/abstract-data-types/graphs": { + "title": "", + "content": "# Graphs\n\n## Introduction\n\nGraphs are simply a collection of **vertices** connected by **edges.** They're very similar to trees, but are much more versatile and don't require hierarchical relationships like trees do.\n\n![A very simple graph.](\u003c../img/assets/image (55).png\u003e)\n\nFor most purposes, we will be working with **simple graphs** that follow two rules:\n\n* There are **no loops** (a connection of a node to itself).\n* There are **no parallel edges** (two edges that connect the same two vertices).\n\n![Don't make these graphs pls. Keep life simple!](\u003c../img/assets/image (56).png\u003e)\n\n## Graph Properties\n\nGraphs can be described by some properties that they could have. Here are the important ones:\n\nA graph can be **directed** if edges are arrows and have a direction, or **undirected** if you can cross edges in any direction.\n\nA graph is **cyclic** if the edges form a loop, or **acyclic** if there are no loops (like in a tree).\n\n![Direction vs. Cycles](\u003c../img/assets/image (57).png\u003e)\n\nGraphs can have **edge labels** if edges are numbered (great for distances). They can also have **vertex weights** if vertices are numbered (great for priorities or costs).\n\n![Edge labels vs. Weights](\u003c../img/assets/image (58).png\u003e)\n\nGraphs are **connected** if all of the vertices are connected with edges, such that you can freely move from one vertex to any other vertex.\n\n![](\u003c../img/assets/image (59).png\u003e)\n\n## Graph Queries\n\nHere are some cool things you can do with graphs:\n\n* Is there a path between two vertices? (s-t path)\n* What is the shortest route between two vertices? (shortest s-t path)\n* Are there cycles? (cycle detection)\n* Can you visit each vertex/edge exactly once? (Euler tour / Hamilton tour)\n* Is a graph connected? (connectivity problem)\n* Is a vertex that disconnects the graph when removed? (single point of failure / biconnectivity)\n* Are two graphs isomorphic?\n* Can a graph be drawn with no crossing edges? (planarity)\n\n## More on Graphs\n\n[Depth First Search (DFS)](../algorithms/searching/depth-first-search-dfs.md), [Breadth First Search (BFS)](../algorithms/searching/breadth-first-search-bfs.md), [Minimum Spanning Trees](../algorithms/minimum-spanning-trees/), [Shortest Paths](../algorithms/shortest-paths/), [Dijkstra's Algorithm](../algorithms/shortest-paths/dijkstras-algorithm.md), [A\\* Search](../algorithms/shortest-paths/a-search.md), [Prim's Algorithm](../algorithms/minimum-spanning-trees/prims-algorithm.md), and [Kruskal's Algorithm](../algorithms/minimum-spanning-trees/kruskals-algorithm.md) all rely on graphs. Graphs are a super useful concept!!!\n", + "lastmodified": "2023-01-03T01:48:32.704428808Z", + "tags": null + }, + "/cs61b/abstract-data-types/hashing": { + "title": "", + "content": "# Hashing and Hash Tables\n\n## Data Indexed Sets: Introduction\n\nSo far, we've explored a whole bunch of ways we can store items, but they aren't really optimized for general searching. What if we could get searching in $\\Theta(1)$ time??? Wouldn't that be nice!\n\nLet's try something: **putting all of our data in a massive array.** Let's say that we know all our data falls into the range from 0 to 10,000 and make an array of 10,000 length to hold stuff.\n\n![](\u003c../img/assets/image (86).png\u003e)\n\nHere, it doesn't matter what index each item is stored in- if we want to get \"eecs\" which is stored at key 3, it will be as instantly accessible as \"haas\" which is all the way in 9998.\n\nOf course, this has a **major design flaw** that you can probably see right away. **It takes way too much memory!**\n\n## Hash Codes\n\nLet's figure out a way to get around the issue of space, but still not lose our awesome constant-time property. One way we can do this is to represent each item with a **hash code** and store them into the index with that hash code.\n\nFor instance, let's use the **first letter of a word** as the hash code. We have just turned a nearly infinite space of possibilities into something that can be stored in just **26** **buckets.**\n\n![](\u003c../img/assets/image (87).png\u003e)\n\nWhile this solution is great, it still has another **major drawback**, which can be illustrated with this example:\n\n![](\u003c../img/assets/image (88).png\u003e)\n\nIn the worst case, this just turns back into a **linked list!** That means the runtime just went from O(1) to O(n), and that's no good.\n\n## Good Hash Codes\n\nIf we can somehow create a \"good\" hash code, we can prevent things like the example above from happening because there shouldn't be a clear pattern in what buckets different objects go to. More specifically, a good hash code:\n\n* Ensures that two objects that are **equal** have the **same hash code.**\n* Ensures that **no distinguishable pattern** can be made out of hash codes from different objects.\n* Returns a **wide variety** of hash codes (not just putting everything into a single bucket, for example).\n\nLuckily, Java already handles hash code generation for us using the `hashCode()` function in the Object class. This function returns an **integer** that can be used to create good hash tables.\n\n## Dynamic Resizing\n\nLet's add another feature to our hash table: **dynamic resizing.** This means that the number of buckets will increase proportionally to the number of items in the set.\n\nOne fairly simple way to do this with a numerical hash code is to mod the hash code by the number of buckets to get which bucket an item is stored in. For example, if a item has hash code `129382981` and we have `10` buckets, then we put it in bucket `1`, or `129382981 % 10`.\n\nIn order to do this, we'll choose a **load ratio** at which to resize. This load ratio is calculated as `N/M`, where N is the number of items and M is the number of buckets. For example, a load ratio of 2 will mean the table resizes when, on average, each bucket has 2 items in it.\n\nWhen resizing, we must **recompute all the hash codes** so that we can balance out all of the buckets again.\n\nThis has some cool runtime implications that are closely related to [Amortization](../asymptotics/amortization.md). Like what happened in the dynamically resizing array, resizing hash tables like this is also a $\\Theta(1)$ operation. Nice!\n\n## Java Hash Tables\n\nIn Java, hash tables are used in the data structures `HashSet` and `HashMap` which are the most popular implementation of sets and maps.\n\nThese two implementations provide **fantastic performance** and **don't require values to be comparable** like trees do.\n\nHowever, they have a drawback that must be considered: **objects cannot be modified after they are put into the hash table.** This is because mutating an object will change its hash code, which means that the object will be lost forever since its bucket doesn't match the current hash code!\n\nIf the built-in hash code generator isn't what is needed (like you want two objects to be equal if they have the same size, for instance), you can override the `hashCode()` method. **Be careful when doing this** because `hashCode()` relies on `equals()` to find which bucket objects are in! So, if hashCode is overridden, it is highly recommended to override equals as well to ensure that they are compatible.\n", + "lastmodified": "2023-01-03T01:48:32.704428808Z", + "tags": null + }, + "/cs61b/abstract-data-types/union-find-disjoint-sets": { + "title": "", + "content": "# Union Find (Disjoint Sets)\n\n{% hint style=\"info\" %}\nThis is not a complete entry, because I feel like existing course materials already cover this in an extremely intuitive manner.\\\nSee[ lab 14](https://inst.eecs.berkeley.edu/\\~cs61b/sp20/materials/lab/lab14/index.html) for an guide on how to implement your own Union Find structure!\n{% endhint %}\n\nThe Union Find data structure is a way of representing a bunch of nodes that are connected to each other in subsets. It's used in [Kruskal's Algorithm](../algorithms/minimum-spanning-trees/kruskals-algorithm.md) among other things.\n\nUnion Find is named as such because it supports two functions, **find** (which returns the group that a value is contained in), and **union** (which connects two values to form a single group).\n\nUnion Find tracks each set with an ID, typically **the value of the root of each set.** In the sections below, we'll discuss how to add an item to a set, as well as figure out which set an existing item is in.\n\n## Union\n\nIn order to **join two values together,** we need to use the **union** function. Let's see what it does visually:\n\n![Calling union(1,2).](\u003c../img/assets/image (78).png\u003e)\n\nThere are lots of ways to represent this behavior. One possible method is to keep an **array of parent values** corresponding to each actual value. In the example above, for instance, we can choose 1 as our parent and make 2 fall under that. Let's see how this might work:\n\n![Parents list.](\u003c../img/assets/image (79).png\u003e)\n\nNow, let's say we call `union(3,2)`. We can just set the parent of 3 to 2, as to create a structure like this:\n\n![union(1,2) followed by union(3,2)](\u003c../img/assets/image (80).png\u003e)\n\nThis looks a lot like a tree!\n\nYou might have noticed that this looks like a **spindly tree** though, which is bad for runtime! Perhaps we can convert it to the equivalent of a bushy tree- the union function can be made much more efficient using tricks such as WeightedQuickUnion and Path Compression. Watch [this playlist](https://www.youtube.com/watch?v=JNa8BRRs8L4\\\u0026list=PL8FaHk7qbOD59HbdZE3x52KOhJJS54BlT\\\u0026index=1) for more information!\n\n## Find\n\nFirst, let's explore how to implement an efficient way to **find which set a value is in.** Using the union function from above, we can do this pretty easily with this simple algorithm:\n\n* If the parent is 0, simply return the value.\n* If the parent is not 0, return the result of calling the function on the parent value.\n\nIf we follow this algorithm on the example in the Union section, we can see that calling `find(3)` will go to `2`, then finally to `1` and return `1`.\n", + "lastmodified": "2023-01-03T01:48:32.704428808Z", + "tags": null + }, + "/cs61b/algorithms/minimax": { + "title": "", + "content": "# Minimax Algorithm\n\n## Game Trees\n\nThe Minimax algorithm is often used for making AI's for turn-based games. It relies on the use of a type of **game tree,** which maps out all of the possible moves that players can make.\n\nIn the tree, there are two types of nodes: **maximizing nodes** and **minimizing nodes.** The max-nodes represent **you**- you want to make your position as advantageous as possible (maximizing your score). The min-nodes represent **your opponent-** they want to make you do as poorly as possible (minimizing your score).\n\nThe scores themselves are generated using a **heuristic function** that assesses the current game state and returns a number based on which player has an advantage, and to what extent. **This heuristic is totally up to you to figure out and has very few constraints.** There are a couple rules, however:\n\n* Heuristic functions must return **positive values** if you're doing better than your opponent, and **negative values** if your opponent is doing better.\n* Heuristic functions must return the **maximum value** for a state in which you won, and the **minimum value** for a state in which your opponent won.\n\nIn most games, you and your opponent will take turns, so each layer will alternate node type, like this:\n\n![](\u003c../img/assets/image (99).png\u003e)\n\nIn most games, this tree will spiral out of control because there are far too many nodes to possibly analyze (maybe even an infinite number)! Therefore, we need to set a **depth** to stop searching and compute a heuristic. For example, if the depth is **3**, it'll look something like this:\n\n![](\u003c../img/assets/image (100).png\u003e)\n\nNow that the tree has bottomed out at the heuristic layer, we can start going back up to figure out which move we should make! The rules are simple: **min-nodes take the smallest of the values** while **max-nodes take the largest of the values.** Here's the first layer, for example:\n\n![](\u003c../img/assets/image (101).png\u003e)\n\nHere's the entire tree filled out:\n\n![](\u003c../img/assets/image (102).png\u003e)\n\nAnd here's the minimax algorithm in pseudocode format:\n\n```python\ndef minimax_value(s: MinimaxNode):\n if is_terminal(s):\n return s.value\n elif s.player == Maximizing:\n return max(minimax_value(c) for c in s.children)\n elif s.player == Minimizing:\n return min(minimax_value(c) for c in s.children)\n```\n\n## **Alpha-Beta Pruning**\n\nWe can make our tree **even more efficient** by simply ignoring all of the branches that will lead to results that will **never be chosen.** Here, we'll assume that **both players play optimally** (choose the best move for their particular node).\n\nIn the example above, we can see that the 7 on the right will **never need to be visited** because we **already know that 5 will be chosen.**\n\nIn order to do this, we'll introduce two additional parameters, **alpha** and **beta.** Here are the rules:\n\n* **Alpha** starts out as **negative infinity** and is set by **max nodes** to their current value.\n* **Beta** starts out as **positive infinity** and is set by **min nodes** to their current value.\n* A node **passes its alpha and beta values** onto its children.\n* If **alpha is greater than beta (**$\\alpha \\ge \\beta$**),** the branch will be **pruned** (no longer visited).\n\nHere are the step-by-step instructions on how to process a node:\n\n1. Copy the alpha and beta values from the parent node. (If no parent node exists, then initialize alpha to negative infinity and beta to positive infinity.\n2. For every branch:\n 1. Recursively process the branch.\n 2. Update the current alpha/beta value depending on the value of the branch after processing. (MaxNodes can only update alpha, and MinNodes can only update beta.)\n 3. If $\\alpha \\ge \\beta$**,** then prune the rest of the branches (stop this loop).\n3. Set the value of this node to the biggest (MaxNode) or smallest (MinNode) value seen.\n\nThe pseudocode for alpha-beta pruning is as follows:\n\n```python\n```\n\nThis is a pretty tough concept to grasp, and that's why I've illustrated how it works below. Read on!\n\n## A Story of Minimax Nodes: An Intuitive Understanding\n\nMinimax is quite difficult to understand just by studying its rules. In order to really know what's going on, we need to know why we have all of these rules and what everything represents. Here's how I think about it:\n\n![](\u003c../img/assets/image (24).png\u003e)\n\n![](\u003c../img/assets/image (25).png\u003e)\n\n![](\u003c../img/assets/image (27).png\u003e)\n\n![](\u003c../img/assets/image (28).png\u003e)\n\n![](\u003c../img/assets/image (29).png\u003e)\n\n![](\u003c../img/assets/image (30).png\u003e)\n\n![](\u003c../img/assets/image (31).png\u003e)\n\n![](\u003c../img/assets/image (33).png\u003e)\n\n_NOTE: The 5's in the above image should all be 7's. This will be corrected soon (tm)._\n\n\n\n## Practice Problems\n\n{% tabs %}\n{% tab title=\"Question 1\" %}\nHere's a tree. Figure out:\n\n* What values each of the nodes report\n* Which branches are pruned\n* The alpha and beta values at each visited node\n\n![](\u003c../img/assets/image (34).png\u003e)\n{% endtab %}\n\n{% tab title=\"Q1 Answer\" %}\nHere's my answer! The green arrows denote the order in which the nodes are visited. Note that the branches are pruned every time **alpha is greater than beta.**\n\n![](\u003c../img/assets/image (35).png\u003e)\n{% endtab %}\n{% endtabs %}\n\nThis was just an ordinary problem and **might not be enough to ensure that you fully understand minimax trees**! Here are some checks you can do to ensure that your understanding is strong:\n\n* Figure out what the tree returns and prunes intuitively _without_ finding any alpha or beta values.\n* Make your own minimax tree problem like the one above and solve it. Are you confident in your answer (since no answer key exists)?\n* Make a minimax tree that's missing some values, and try to find all possible values that fit in there such that the branch will become pruned.\n* Implement the minimax algorithm in Java.\n", + "lastmodified": "2023-01-03T01:48:32.708428787Z", + "tags": null + }, + "/cs61b/algorithms/minimum-spanning-trees/README": { + "title": "", + "content": "\n# Minimum Spanning Trees\n\n## Spanning Tree Definition\n\nA **spanning tree** T is a subgraph of a graph G where T:\n\n* Is connected (there's a path to every vertex)\n* Is acyclic (no cycles)\n* Includes every vertex (spanning property)\n\n**Notice:** the first two properties defines a tree structure, and the last property makes the tree spanning.\n\nA **minimum spanning tree** is a spanning tree with minimum total edge weight.\n\nExample: I want to connect an entire town with wiring and would like to find the optimal wiring connection that connects everyone but uses the least wire.\n\n## MST vs. Shortest Path Tree\n\nIn contrast to a shortest path tree, which is essentially the solution tree to running Dijkstra’s with root node = source vertex, a MST has no source. However, it is possible for the MST to be the same as the SPT.\n\nWe can think of the MST as a global property for the entire graph, as opposed to SPT which depends on which node is the source node.\n\nIf the edges of the graph are not unique, there’s a chance that the MST is not unique.\n\n## Cuts Property\n\n* A **cut** is defined as assigning the nodes in a graph into two sets.\n* A **crossing edge** is an edge that connects two nodes that are in different sets\n* The smallest crossing edge is the crossing edge with smallest weight\n\nThe **Cut Property** states that the smallest crossing edge is always going to be in the MST, no matter how the cut is made.\n\n![](\u003c../../img/assets/image (109).png\u003e)\n", + "lastmodified": "2023-01-03T01:48:32.708428787Z", + "tags": null + }, + "/cs61b/algorithms/minimum-spanning-trees/kruskals-algorithm": { + "title": "", + "content": "\n# Kruskal's Algorithm\n\n{% hint style=\"warning\" %}\nBefore reading, review [Minimum Spanning Trees](./) and [Union Find (Disjoint Sets)](../../abstract-data-types/union-find-disjoint-sets.md) as they both make Kruskal's algorithm possible!\n{% endhint %}\n\n## Conceptual Overview\n\nKruskal's algorithm is another optimal way to construct a **minimum spanning tree**. It's benefits are that it is conceptually very simple, and easy to implement. The idea is that first we sort all the edges of the graph in order of increasing weight. Then, add the smallest edge to the MST we are constructing unless this creates a cycle in the MST. Repeat until V - 1 edges total.\n\n## Detailed Breakdown\n\nIn order to optimally check if adding an edge to our MST creates a cycle, we will use a **WeightedQuickUnion** object. (See [Union Find (Disjoint Sets)](../../abstract-data-types/union-find-disjoint-sets.md) for a recap on what this is.) This is used because checking if a cycle exists using a WeightedUnionFind object boils down to one `isConnected()` call, which we know takes $\\Theta(\\log(N))$.\n\nTo run the algorithm, we start by adding all the edges into a [PriorityQueue](../../abstract-data-types/collections/stacks-and-queues.md). This gives us our edges in sorted order. Now, we iterate through the PriorityQueue by removing the edge with highest priority, checking if adding it forms a cycle, and adding it to our MST if it doesn't form a cycle.\n\nLet's see an example of Kruskal's Algorithm in action!\n\nHere, we start with a simple graph and have sorted all of its edges into a priority queue.\n\n![](\u003c../../img/assets/image (103).png\u003e)\n\nSince the edge **DE** is the shortest, we'll add that to our UnionFind first. In the process, we'll **remove DE from the priority queue.**\n\n![](\u003c../../img/assets/image (104).png\u003e)\n\nWe'll do the same thing with the next shortest path, **DC.**\n\n![](\u003c../../img/assets/image (105).png\u003e)\n\nNow, let's move on to **AB.** Notice that this time, connecting A and B creates another **disjoint set!** Unlike Prim's Algorithm, Kruskal's Algorithm does not guarantee that a solution will form a tree structure until the very end.\n\n![](\u003c../../img/assets/image (106).png\u003e)\n\nNow, let's connect **BC.**\n\n![](\u003c../../img/assets/image (107).png\u003e)\n\nSince **CE** and **BD** would both form cycles if connected, **we are done 😄** Here's the final tree:\n\n![](\u003c../../img/assets/image (108).png\u003e)\n\n## PseudoCode\n\n```java\npublic class Kruskals() {\n\n public Kruskals() {\n PQ edges = new PriorityQueue\u003c\u003e();\n ArrayList\u003cEdge\u003e mst = new ArrayList\u003c\u003e();\n }\n\n public void doKruskals(Graph G) {\n for (e : G.edges()) {\n PQ.add(e);\n }\n WeightedQU uf = new WeightedQU(G.V());\n Edge e = PQ.removeSmallest();\n int v = e.from();\n int w = e.to();\n if (!uf.isConnected(v, w)) {\n uf.union(v, w);\n mst.add(e);\n }\n\n }\n}\n```\n\n## Runtime Analysis\n\nLeft as an exercise to the reader 😉\n\n{% hint style=\"info\" %}\nSomeone's been reading too much [LADR](https://www.springer.com/gp/book/9783319110790)...\\\n(The answer is $\\Theta(E\\log(E))$by the way. Try to convince yourself why!)\n{% endhint %}\n", + "lastmodified": "2023-01-03T01:48:32.708428787Z", + "tags": null + }, + "/cs61b/algorithms/minimum-spanning-trees/prims-algorithm": { + "title": "", + "content": "\n# Prim's Algorithm\n\n{% hint style=\"warning\" %}\nBefore reading, review [Minimum Spanning Trees](./README), as that is the foundation of Prim's algorithm!\n{% endhint %}\n\n## Conceptual Overview\n\nPrim's algorithm is an optimal way to construct a **minimum spanning tree**. It basically starts from an arbitrary vertex, then considers all its immediate neighbors and picks the edge with smallest weight to be part of the MST. **Note:** this creates a cut in the graph, where the two nodes in the MST being constructed are in one set, and every other vertex of the graph is in another set.\n\nNow, the edges taken into consideration include all immediate neighbors of every node in the MST. Add the edge that has the smallest weight to the MST. Repeat until every vertex has been visited. The result is an MST for the graph.\n\n## Detailed Breakdown\n\nThe way Prim's algorithm is usually implemented is via [PriorityQueue](../../abstract-data-types/collections/stacks-and-queues.md), `edgeTo` array, and` distTo` array. You will soon see its similarities to [Dijkstra's](../shortest-paths/dijkstras-algorithm.md).\n\nFirst, insert all vertices into the PriorityQueue, storing vertices in order of **distance from MST**. Then, remove vertex with highest priority in the PriorityQueue and relax its edges. In each of these iterations, the distTo and edgeTo arrays will be updated for each vertex v if the **weight of the edge is smaller than the current value in distTo\\[v]**. In other words, only update if the distance from the MST to the vertex is the best seen so far. This is a very important point, and is one of the subtleties that makes Prim's algorithm fundamentally different from Dijkstra's.\n\n## Useful Properties/Invariants\n\nThe MST under construction is **always connected.**\n\n## Pseudocode\n\n```java\npublic class Prims() {\n\n public Prims() {\n PQ = new PriorityQueue\u003c\u003e();\n edgeTo = new Edge[numVertices];\n distTo = new Dist[numVertices];\n marked = new boolean[numVertices];\n }\n\n public void doPrims() {\n PQ.add(sourceVertex, 0);\n for(v : allOtherVertices) {\n PQ.add(v, INFINITY);\n }\n while (!PQ.isEmpty()) {\n Vertex p = PQ.removeSmallest();\n marked[p] = true;\n relax(p);\n }\n }\n\n public void relax(Vertex p) {\n for (q : p.neighbors()) {\n if (marked[q]) { continue; }\n if (q.edgeWeight \u003c distTo[q]) {\n distTo[q] = q.edgeWeigth;\n edgeTo[q] = p;\n PQ.changePriority(q, distTo[q]);\n }\n }\n }\n}\n```\n\nLooking at this pseudocode, the resemblance to Dijkstra's makes them seem nearly identical. But hopefully you've read the conceptual overviews first, and you understand the remarkable subtlety that leads to two very fundamentally different algorithms.\n\n## Runtime Analysis\n\nThis is the same as for Dijkstra's Algorithm.\n\n**Unsimplified:**\n\n$\n\\theta(V * log(V) + V * log(V) + E * log(V))\n$\n\n**Simplified:**\n\n$\n\\theta(E * log(V))\n$\n\n**Explanation:**\n\n* each add operation to PQ takes log(V), and perform this V times\n* each removeFirst operation to PQ takes log(V) and perform this V times\n* each change priority operation to PQ takes log(V), perform this at most as many times as there are edges\n* everything else = O(1)\n* usually, there are more or equal edges compared to the number of vertices.\n\n## Demo\n\n[https://docs.google.com/presentation/d/1GPizbySYMsUhnXSXKvbqV4UhPCvrt750MiqPPgU-eCY/edit#slide=id.g9a60b2f52\\_0\\_0](https://docs.google.com/presentation/d/1GPizbySYMsUhnXSXKvbqV4UhPCvrt750MiqPPgU-eCY/edit#slide=id.g9a60b2f52\\_0\\_0)\n", + "lastmodified": "2023-01-03T01:48:32.708428787Z", + "tags": null + }, + "/cs61b/algorithms/searching/README": { + "title": "", + "content": "# Searching\n\nThis section will cover some ways to find values in a set.\n\n{% content-ref url=\"binary-search.md\" %}\n[binary-search.md](binary-search.md)\n{% endcontent-ref %}\n\n{% content-ref url=\"depth-first-search-dfs.md\" %}\n[depth-first-search-dfs.md](depth-first-search-dfs.md)\n{% endcontent-ref %}\n\n{% content-ref url=\"breadth-first-search-bfs.md\" %}\n[breadth-first-search-bfs.md](breadth-first-search-bfs.md)\n{% endcontent-ref %}\n\n", + "lastmodified": "2023-01-03T01:48:32.708428787Z", + "tags": null + }, + "/cs61b/algorithms/searching/binary-search": { + "title": "", + "content": "# Binary Search\n\nBinary search is a way of finding a specific node in a tree. It only works on [binary trees](../../abstract-data-types/binary-trees/) due to its helpful sorted property. It simply traverses the tree, moving left if the current node is too large or right if it is too small.\n\nBinary search runs in $\\Theta(\\log(n))$ time for bushy trees, which is also the number of layers in a tree.\n\n## The Algorithm\n\n```java\npublic BST find(BST T, Key sk) {\n if (T == null) {\n return null;\n }\n if (sk.equals(T.key)) {\n return T;\n } else if (sk \u003c T.key) {\n return find(T.left, sk);\n } else {\n return find(T.right, sk);\n }\n}\n```\n", + "lastmodified": "2023-01-03T01:48:32.708428787Z", + "tags": null + }, + "/cs61b/algorithms/searching/breadth-first-search-bfs": { + "title": "", + "content": "# Breadth First Search (BFS)\n\nBreadth First Search (BFS), like [Depth First Search (DFS)](depth-first-search-dfs.md), is a method of **traversing a graph.** BFS simply traverses in a different order, but otherwise is very similar to DFS.\n\nThe main difference is that BFS **visits all children before any subgraphs.** In a tree, we call this **level order.**\n\n![](\u003c../../img/assets/image (110).png\u003e)\n\nFor the example tree above, a level order traversal would go in this order: **D B F A C E G.**\n\n## Step by Step\n\n**Let's see how we might implement BFS.**\n\nSome data structures we will need are:\n\n* A graph to traverse.\n* A queue **Q** to keep track of which nodes need to be processed next.\n* A list of booleans **marked** to keep track of which nodes were already visited.\n* (Optional) **edgeTo** and **distTo** to keep track of information that might be useful for other applications (like [Dijkstra's Algorithm](../shortest-paths/dijkstras-algorithm.md)).\n\nFirst, let's start with a vertex in the graph by marking it and adding it to the queue.\n\n![](\u003c../../img/assets/image (111).png\u003e)\n\nThe next step is to **remove A from the queue** and **add its children** (B and C) **to the queue.** Also, we need to **mark all of the children.**\n\n![](\u003c../../img/assets/image (112).png\u003e)\n\nNext, we'll move onto the **next item on the queue** (B). We'll do the same thing that we did with A: remove B, mark all its children, and add its children to the queue. **Since C is already marked, we do not add it to the queue again.**\n\n![](\u003c../../img/assets/image (113).png\u003e)\n\nNow, we'll move on to the next item on the queue, C, and do the same thing. Again, we won't add C or A because they are both marked.\n\n![](\u003c../../img/assets/image (114).png\u003e)\n\nFinally, we'll visit the two remaining nodes in the queue, D and E. Since all of the nodes are marked now, there aren't any other nodes to visit.\n\n", + "lastmodified": "2023-01-03T01:48:32.712428766Z", + "tags": null + }, + "/cs61b/algorithms/searching/depth-first-search-dfs": { + "title": "", + "content": "# Depth First Search (DFS)\n\n## Depth First Traversal\n\nBefore we move on to searching, let's talk about **traversing. Traversal** is the act of **visiting nodes in a specific order.** This can be done either in trees or in graphs.\n\nFor trees in particular, there are **three main ways** to traverse.\n\n![The example tree we will use for traversal illustrations.](\u003c../../img/assets/image (89).png\u003e)\n\nThe first way is **inorder** traversal, which visits **all left children**, then **the node itself,** then **all right children.** The end result should be that the nodes were visited in **sorted order.**\n\nThe second way is **preorder** traversal, which visits **the node itself first,** then **all left children,** then **all right children.** This method is useful for applications such as printing a directory tree structure.\n\nThe third way is **postorder** traversal, which visits **all left children,** then **all right children,** then **finally the node itself.** This method is useful for when operations need to be done on all children before the result can be read in the node, for instance getting the sizes of all items in the folder.\n\nHere are some pseudocodey algorithms for tree traversals.\n\n```java\n// INORDER will print A B C D E F G\nvoid inOrder(Node x) {\n if (x == null) return;\n inOrder(x.left);\n print(x);\n inOrder(x.right);\n}\n\n// PREORDER will print D B A C F E G\nvoid preOrder(Node x) {\n if (x == null) return;\n print(x);\n preOrder(x.left);\n preOrder(x.right);\n}\n\n// PREORDER will print A C B E G F D\nvoid postOrder(Node x) {\n if (x == null) return;\n preOrder(x.left);\n preOrder(x.right);\n print(x);\n}\n```\n\n## Depth First Search in Graphs\n\nGraphs are a little more complicated to traverse due to the fact that they could have **cycles** in them, unlike trees. This means that we need to **keep track of all the nodes already visited** and add to that list whenever we encounter a new node.\n\nDepth First Search is great for determining if everything in a graph is connected.\n\nHere's an outline of how this might go:\n\n* Keep an array of 'marks' (true if node has been visited) and, optionally, an edgeTo array that will automatically keep track of how to get to each connected node from a source node\n* When each vertex is visited:\n * Mark the vertex\n * For each adjacent unmarked vertex:\n * Set edgeTo of that vertex equal to this current vertex\n * Call the recursive method on that vertex\n\nLike trees, DFS can be done **inorder, preorder, or postorder.** It's nearly identical behavior to trees, with the addition of the marks array.\n", + "lastmodified": "2023-01-03T01:48:32.712428766Z", + "tags": null + }, + "/cs61b/algorithms/searching/dijkstras": { + "title": "", + "content": "# Dijkstra's Algorithm \n\n## One sentence overview:\nVisit vertices in order of best-known distance from source; on visit relax every edge from the visited vertex.\n\n## Dijkstra's vs BFS big idea:\nBFS returns the shortest paths in an unweighted graph, where the shortest path is just defined to be the fewest number of edges traveled along a path. In Djikstras, we can generalize the breadth-first traversal to find the path with the lowest cost, where the cost is determined by different weights on the edges. Djikstras uses a PQueue to maintain the path with lowest cost from the starting node to every other node. \n\n## Important points: \n- always visits vertices in order of total distance from source\n- relaxation always fails on edges to visited vertices \n- guarantees to work optimally as long as edges are all non-negative\n- solution always a tree form, true for undirected graphs\n- can think of as union of shortest paths to all vertices \n- edges in solution tree always has V-1 edges, where V = #vertices b/c for each vertex, exactly one input source except the root \n\n## Key invariants:\n1. edgeTo[v] always contains best known predecessor for v\n2. distTo[v] contains best known distance from source to v\n3. PQ contains all unvisited vertices in order of distTo\n\n\n## PseudoCode:\n PQ.add(sourceVertex, 0)\n For v in allOtherVertices:\n\t PQ.add(v, infinity)\n While !PQ.isEmpty():\n\t P = PQ.removeSmallest\n\t relax(P)\n\t \n (relaxing edge p → q)\n relax(Vertex p):\n\t If distTo[p] + q \u003c distTo[q]:\n\t\t distTo[q] = distTo[p] + q\n\t\t edgeTo[q] = p\n\t\t PQ.changePriority(q, distTo[q])\n\n\t\t\n\n## Runtime:\n$O(V*log(V) + V*log(V) + E*log(V)) → O(E*log(V)) $\n- each add operation to PQ takes log(V), and perform this V times\n- each removeFirst operation to PQ takes log(V) and perform this V times \n- each change priority operation to PQ takes log(V), perform this as many times as there are edges\n- everything else = O(1) \n- usually # edges \u003e= # vertices \n\n\n# A* Algorithm\n- Literally just Dijkstra’s, but with an added heuristic function to consider. Motivation: can help bias our algorithm in the right direction so that it doesn’t make a bunch of bad moves. \n- For each vertex instead of only comparing distTo[v], also have a heuristic evaluation, so visit vertices in order of d(goal, v) + h(v, goal)\n- Not all vertices get visited, algorithm only cares about finding the best path to the goal, and not any other vertex (that’s how the heuristic will be designed)\n- heuristic must be both:\n * Admissible - heuristic of each vertex returns a cost that is \u003c= the true cost/distance i.e. h(A) \u003c= cost(A, goal)\n * Consistent - difference between heuristics of two vertices \u003c= true cost between them i.e. h(A) - h(B) \u003c= cost(A, B)\n- Demo:https://docs.google.com/presentation/d/177bRUTdCa60fjExdr9eO04NHm0MRfPtCzvEup1iMccM/edit#slide=id.g369665031c_0_350", + "lastmodified": "2023-01-03T01:48:32.712428766Z", + "tags": null + }, + "/cs61b/algorithms/shortest-paths/README": { + "title": "", + "content": "# Shortest Paths\n\nWe've seen that Breadth-First Search can help us find the shortest path in an unweighted graph, where the shortest path was just defined to be the fewest number of edges traveled along a path. In the following shortest-paths algorithms, we will discover how we can generalize the breadth-first traversal to find the path with the lowest total cost, where the cost is determined by different weights on the edges.\n", + "lastmodified": "2023-01-03T01:48:32.712428766Z", + "tags": null + }, + "/cs61b/algorithms/shortest-paths/a-search": { + "title": "", + "content": "\n# A\\* Search\n\n{% hint style=\"warning\" %}\nIn order to understand A\\*, you'll need to review [Dijkstra's Algorithm](dijkstras-algorithm.md) first! Come back after you're done with that 😉\n{% endhint %}\n\n## A\\* Algorithm\n\nThe A\\* Search Algorithm is **incredibly similar to Dijkstra's Algorithm** with one addition: a **heuristic function.**\n\nThis heuristic function calculates weights of a path **from a vertex to a goal vertex.** This way, we can help bias our algorithm in the right direction so that it doesn’t make a bunch of bad moves.\n\nThis has an important implication: **not all vertices get visited.** The algorithm only cares about finding the best path to the goal, and not any other vertex (assuming we design our heuristic well).\n\nThe **order** that the vertices get visited is lowest **distance + heuristic**. This is basically the same as Dijkstra's, just with that added heuristic term.\n\n## What's a good heuristic?\n\nHeuristic functions can be really tricky to design, since there isn't much to go off of.\n\n**A good heuristic has these two properties:**\n\n* **Admissible** - heuristic of each vertex returns a cost that is \u003c= the true cost/distance i.e. h(A) \u003c= cost(A, goal)\n* **Consistent** - difference between heuristics of two vertices \u003c= true cost between them i.e. h(A) - h(B) \u003c= cost(A, B)\n\n## **Want more?**\n\n[Here's a cool demo!](https://docs.google.com/presentation/d/177bRUTdCa60fjExdr9eO04NHm0MRfPtCzvEup1iMccM/edit#slide=id.g369665031c\\_0\\_350)\n\n", + "lastmodified": "2023-01-03T01:48:32.712428766Z", + "tags": null + }, + "/cs61b/algorithms/shortest-paths/dijkstras-algorithm": { + "title": "", + "content": "\n# Dijkstra's Algorithm\n\n{% hint style=\"warning\" %}\nBefore continuing, make sure you're comfortable with [Graphs](../../abstract-data-types/graphs.md), [Stacks and Queues](../../abstract-data-types/collections/stacks-and-queues.md), and [Shortest Paths](./).\n{% endhint %}\n\n## One sentence overview\n\nVisit vertices in order of best-known distance from source; on visit, relax every edge from the visited vertex.\n\n## Detailed Breakdown\n\nDjikstras uses a **PriorityQueue** to maintain the path with lowest cost from the starting node to every other node, an **edgeTo** array to keep track of the best known predecessor for each vertex, and a **distTo** array to keep track of the best known distance from the source vertex to every other vertex.\n\n**Relaxing** the edges of a vertex v just refers to the process of updating edgeTo\\[n] for each neighbor n to v.\n\nYou'll see in the pseudocode and diagrams below that succesful relaxation only occurs when the edge connecting the vertex being visited to one of its neighbors yields a smaller total distance than the current shortest path to that neighboring vertex that the algorithm has seen.\n\nNow, here's a demonstration on how it works! Let's start out with this graph:\n\n![](\u003c../../img/assets/image (92).png\u003e)\n\nWe'll start at node A and try to figure out the shortest path from A to each node. Since we have no idea how far each node is, we'll take the conservative guess that everything is infinitely far away ♾😎\n\nThe first thing we have to do is update A's adjacent nodes, which are **B** and **D**. Since there's only one known path to each, it shouldn't be too hard to see why we need to update the values below. One thing to note is that the priority queue **sorts the vertices by the distance it takes to get there.**\n\n![](\u003c../../img/assets/image (93).png\u003e)\n\nNow, we have a choice to move on to either **B** or **D**. Since B has a **shorter distance,** we'll move on to that first. When we move on, we have to **remove that value from the priority queue** and **update all of its neighbors.** Here, we see that going from **B to D** is **shorter** than **A to D**, so we have to **update distTo AND edgeTo of D** to reflect this new, shorter path. **This process** (updating each adjacent node) **is called relaxing the edges of a node.**\n\n![](\u003c../../img/assets/image (94).png\u003e)\n\nNow, let's move onto **D** since it has the next shortest path. Again, we **remove D from the priority queue** and **relax C** since we found a shorter path.\n\n![](\u003c../../img/assets/image (95).png\u003e)\n\nFinally, we'll move onto **C** as that has the next shortest path in the priority queue. This will reveal our final node, **E**.\n\n![](\u003c../../img/assets/image (96).png\u003e)\n\nSince **the priority queue is now empty,** our search is done! 😄 Here's what the final solution looks like **in a tree form**:\n\n![Dijkstra's Algorithm ALWAYS produces a solution in a tree format.](\u003c../../img/assets/image (98).png\u003e)\n\nIt's a very spindly tree indeed, but hopefully it demonstrates that the result is **acyclic**.\n\n## Properties of Dijkstra's Algorithm\n\n**Dijkstra's Algorithm has some invariants (things that must always be true):**\n\n1. edgeTo\\[v] always contains best known predecessor for v\n2. distTo\\[v] contains best known distance from source to v\n3. PQ contains all unvisited vertices in order of distTo\n\n**Additionally, there are some properties that are good to know:**\n\n* always visits vertices **in order of total distance from source**\n* relaxation always **fails on edges to visited vertices**\n* guarantees to work optimally **as long as** **edges are all non-negative**\n* solution always creates a **tree form.**\n* can think of as **union of shortest paths to all vertices**\n* **edges in solution tree always has V-1 edges**, where V = the number of vertices. This is because every vertex in the tree except the root should have **exactly one input.**\n\n## Pseudocode\n\n```java\npublic Class Djikstra() {\n\n public Djikstra() {\n PQ = new PriorityQueue\u003c\u003e();\n distTo = new Distance[numVertices];\n edgeTo = new Edge[numVertices];\n }\n\n public void doDijkstras(Vertex sourceVertex) {\n PQ.add(sourceVertex, 0);\n for(v : allOtherVertices) {\n PQ.add(v, INFINITY);\n }\n while (!PQ.isEmpty()) {\n Vertex p = PQ.removeSmallest();\n relax(p);\n }\n }\n // Relaxes all edges of p\n void relax(Vertex p) {\n for (q : p.neighbors()) {\n if (distTo[p] + q.edgeWeight \u003c distTo[q]) {\n distTo[q] = distTo[p] + q.edgeWeight;\n edgeTo[q] = p;\n PQ.changePriority(q, distTo[q]);\n }\n }\n }\n}\n```\n\n## Runtime Analysis\n\n**Unsimplified:**\n\n$\n\\theta(V * log(V) + V * log(V) + E * log(V))\n$\n\n**Simplified:**\n\n$\n\\theta(E * log(V))\n$\n\n**Explanation:**\n\n* each add operation to PQ takes log(V), and perform this V times\n* each removeFirst operation to PQ takes log(V) and perform this V times\n* each change priority operation to PQ takes log(V), perform this at most as many times as there are edges\n* everything else = O(1)\n* usually, there are more or equal edges compared to the number of vertices.\n", + "lastmodified": "2023-01-03T01:48:32.712428766Z", + "tags": null + }, + "/cs61b/asymptotics/amortization": { + "title": "", + "content": "# Amortization\n\n{% hint style=\"warning\" %}\nPlease read [Asymptotic Analysis Basics](asymptotics.md) first. If you don't, none of this will make any sense!\n{% endhint %}\n\n**Amortization** means **spreading out.**\n\nSometimes, an operation takes different amounts of time for different values of $n$. Rather than having to report runtimes for each different case, we can instead average all of them out and report the **amortized runtime.**\n\nThis is especially good for functions where most actions have a low cost, but a few have a high cost. We'll see an example of this further down the page!\n\n## A Case Study: Resizing Arrays\n\nAs you probably know, normal Java arrays don't resize. If we create a `new int[5]` then that array will always have a length of 5.\n\nBut what if we wanted to make an array resize itself every time it reaches capacity? (Like a `List`!) Let's see what happens when we **add one to the array size:**\n\nFirst, we have to make a new array with a new size:\n\n![Example Images](notes/cs61b/img/assets/0.png)\n![Example Images](notes/images/github-actions.png)\n\nThen, we have to copy over all of the old elements over:\n\n![](\u003c../img/assets/image (17).png\u003e)\n\nFinally, we can add in the new element!\n\n![](\u003c../img/assets/image (19).png\u003e)\n\n**Let's analyze the runtime of this operation.**\n\n* A single resizing will take $\\Theta(n)$ time**.**\n* Adding a single element will take $\\Theta(1)$ time**.**\n* Together, a single operation will take $\\Theta(n+1)$ time, which simplifies into $\\Theta(n)$ .\n* Since we're doing a n-operation n times, **the end result is a resizing function that is**$\\Theta(n^2)$. **We can do better with the power of amortization!**\n\n### **What if we doubled the size instead of adding one?**\n\n* A single resizing will take $\\Theta(2n)$ time \\_\\*\\*\\_which simplifies into $\\Theta(n)$ time.\n * We do this every time the array hits a power of 2 (2, 4, 8, 16, 32 ...).\n* Adding a single element will take $\\Theta(1)$ time.\n * We do this every time we add a new element, so in all we add n elements. Therefore, this is an\n * $\\Theta(n)$operation.\n\n**Therefore, the unsimplified function is:** $\\Theta(n + (2 + 4 + 8 ... +2^i))$ where $2^i$ is the largest power of two less than n. This might not seem clear on its own, so let's rewrite it:\n\n$\n\\theta(n + (\\frac{n}{2} + \\frac{n}{4} + ... + 8 + 4 + 2))\n$\n\nIntuitively, this looks like this:\n\n![](\u003c../img/assets/image (39).png\u003e)\n\nMathematically, it looks like this:\n\n$\nn + n\\sum_{n=1}^{n}(\\frac{1}{2})^n\n$\n\nWhich simplifies to $2n$if you recall your power series properties . **Therefore, this approach is** $\\Theta(n)$ **!!**\n\n![](\u003c../img/assets/image (116).png\u003e)\n\n\n\n\n\n", + "lastmodified": "2023-01-03T01:48:32.712428766Z", + "tags": null + }, + "/cs61b/asymptotics/asymptotics": { + "title": "", + "content": "# Asymptotic Analysis Basics\n\n{% hint style=\"warning\" %}\nThis concept is a big reason why a strong math background is helpful for computer science, even when it's not obvious that there are connections! Make sure you're comfortable with Calculus concepts up to [power series](http://tutorial.math.lamar.edu/Classes/CalcII/PowerSeries.aspx).\n{% endhint %}\n\n## An Abstract Introduction to Asymptotic Analysis\n\nThe term **asymptotics,** or **asymptotic analysis,** refers to the idea of **analyzing functions when their inputs get really big.** This is like the **asymptotes** you might remember learning in math classes, where functions approach a value when they get very large inputs.\n\n![](\u003c../img/assets/image (13).png\u003e)\n\nHere, we can see that $y= \\dfrac{x^3}{x^2 + 1}$ looks basically identical to $y = x$ when x gets really big. Asymptotics is all about reducing functions to their eventual behaviors exactly like this!\n\n## That's cool, but how is it useful?\n\nGraphs and functions are great and all, but at this point it's still a mystery as to how we can use these concepts for more practical uses. Now, we'll see how we can **represent programs as mathematical functions** so that we can do cool things like:\n\n* **Figure out how much time or space a program will use**\n* **Objectively tell how one program is better than another program**\n* **Choose the optimal data structures for a specific purpose**\n\nAs you can see, this concept is **absolutely fundamental** to ensuring that you write **efficient algorithms** and choose the **correct data structures.** With the power of asymptotics, you can figure out if a program will take 100 seconds or 100 years to run without actually running it!\n\n## How to Measure Programs\n\nIn order to convert your `public static void Main(String[] args)` or whatever into `y = log(x)`, we need to figure out what `x` and `y` even represent!\n\n**TLDR:** It depends, but the three most common measurements are **time, space,** and **complexity**.\n\n**Time** is almost always useful to minimize because it could mean the difference between a program being able to run on a smartphone and needing a supercomputer. Time usually increases with the **number of operations** being run. Loops and recursion will increase this metric substantially. On Linux, the `time` command can be used for measuring this.\n\n**Space** is also often nice to reduce, but has become a smaller concern now that we can get terabytes (or even petabytes) of storage pretty easily! Usually, the things that take up lots of space are **big lists** and **a very large number of individual objects.** Reducing the size of lists to hold only what you need will be very helpful for this metric!\n\nThere is another common metric, which is known as **complexity** or **computational cost.** This is a less concrete concept compared to time or space, and cannot be measured easily; however, it is highly generalized and usually easier to think about. For complexity, we can simply assign basic operations (like println, adding, absolute value) a complexity of **1** and add up how many basic operation calls there are in a program.\n\n## Simplifying Functions\n\nSince we **only care about the general shape of the function,** we can keep things as simple as possible! Here are the main rules:\n\n* **Only keep the** **fastest growing term.** For example, $log(n) + n$ can be simplified to just $n$since $n$ grows faster out of the two terms.\n* **Remove all constants.** For example, $5log(3n)$ can just be simplified to $log(n)$since constants don't change the overall shape of a function.\n* **Remove all other variables.** If a function is really $log(n + m)$ but we only care about n, then we can simply it into $log(n)$.\n\nThere are two cases where we can't remove other variables and constants though, and they are:\n\n* A polynomial term $n^c$(because $n^2$grows slower than $n^3$, for example), and\n* An exponential term $c^n$(because $2^n$grows slower than $3^n$, for example).\n\n## The Big Bounds\n\nThere are **three** important types of runtime bounds that can be used to describe functions. These bounds put restrictions on how slow or fast we can expect that function to grow!\n\n**Big O** is an **upper bound** for a function growth rate. That means that **the function grows slower or the same rate as the Big O function.** For example, a valid Big O bound for $log(n) + n$ is $O(n^2)$ since $n^2$ grows at a faster rate.\n\n**Big Omega** is a **lower bound** for a function growth rate. That means that **the function grows faster or the same rate as the Big Omega function.** For example, a valid Big Omega bound for $log(n) + n$ is $\\Omega(1)$ since $1$ (a constant) grows at a slower rate.\n\n**Big Theta** is a **middle ground** that describes the function that grows at the **same rate** as the actual function. **Big Theta only exists if there is a valid Big O that is equal to a valid Big Omega.** For example, a valid Big Theta bound for $log(n) + n$ is $\\Theta(n)$ since $n$ grows at the same rate (log n is much slower so it adds an insignificant amount).\n\n\n\n![A comparison of the three bounds.](\u003c../img/assets/image (15).png\u003e)\n\n## Orders of Growth\n\nThere are some **common functions** that many runtimes will simply into. Here they are, from fastest to slowest:\n\n| Function | Name | Examples |\n| --------------------- | ----------- | ------------------------------------------------------ |\n| $\\Theta(1)$ | Constant | System.out.println, +, array accessing |\n| $\\Theta(\\log(n))$ | Log | Binary search |\n| $\\Theta(n)$ | Linear | Iterating through each element of a list |\n| $\\Theta(n\\log(n))$ | nlogn 😅 | Quicksort, merge sort |\n| $\\Theta(n^2)$ | Quadratic | Bubble sort, nested for loops |\n| $\\Theta(2^n)$ | Exponential | Finding all possible subsets of a list, tree recursion |\n| $\\Theta(n!)$ | Factorial | Bogo sort, getting all permutations of a list |\n| $\\Theta(n^n)$ | n^n 😅😅 | [Tetration](https://en.wikipedia.org/wiki/Tetration) |\n\nDon't worry about the examples you aren't familiar with- I will go into much more detail on their respective pages.\n\n![Source: bigocheatsheat.com. Check it out, it's great!](\u003c../img/assets/image (14).png\u003e)\n\n## Asymptotic Analysis: Step by Step\n\n1. Identify the function that needs to be analyzed.\n2. Identify the parameter to use as $n$.\n3. Identify the measurement that needs to be taken. (Time, space, etc.)\n4. Generate a function that represents the complexity. If you need help with this step, [try some problems!](asymptotics-practice.md)\n5. [Simplify](asymptotics.md#simplifying-functions) the function (remove constants, smaller terms, and other variables).\n6. Select the correct bounds (O, Omega, Theta) for particular cases (best, worst, overall).\n", + "lastmodified": "2023-01-03T01:48:32.712428766Z", + "tags": null + }, + "/cs61b/asymptotics/asymptotics-practice": { + "title": "", + "content": "# Asymptotics Practice\n\n{% hint style=\"warning\" %}\nMake sure to review [Asymptotic Analysis Basics](asymptotics.md) before proceeding with these problems.\n{% endhint %}\n\n## Introduction\n\nAsymptotics is a very intuition-based concept that often doesn't have a set algorithm for computing. The best way to get good at analyzing programs is to practice!\n\nWith that said, here are some problems of increasing difficulty for you to enjoy 😊\n\n{% hint style=\"info\" %}\nFor all of the below problems, assume that all undefined functions have a constant O(1) complexity.\n{% endhint %}\n\n## Loops\n\n{% tabs %}\n{% tab title=\"Question 1\" %}\nWhat runtime does this function have?\n\n```java\nvoid throwHalfOfMyItems(int n) {\n for (int i = 0; i \u003c n; i += 1) {\n if (i % 2 == 0)\n throwItem(n);\n }\n}\n```\n{% endtab %}\n\n{% tab title=\"Q1 Answer\" %}\n$\n\\Theta(n)\n$\n\n**Explanation:** The method `throwItem()` runs `n/2` times. Using the simplification rules, we can extract the constant `1/2` to simply get `n`.\n\n![Keep the change, ya filthy animal.](\u003c../img/assets/image (40).png\u003e)\n{% endtab %}\n{% endtabs %}\n\n{% tabs %}\n{% tab title=\"Question 2a\" %}\nWhat runtime does this function have?\n\n```java\nvoid lootShulkerBoxes(int n) {\n for (int box = n; box \u003e 0; box -= 1) {\n for (int stack = 0; stack \u003c n; stack += 1) {\n for (int i = 0; i \u003c 64; i += 1) {\n lootItem(i * stack * box);\n }\n }\n } \n}\n```\n{% endtab %}\n\n{% tab title=\"Q2a Answer\" %}\n$\n\\Theta(n^2)\n$\n\n**Explanation:** There are **three** nested loops in this problem. Whenever there are nested loops whose runtimes are independent of each other, we need to **multiply** the runtimes in each loop.\\\nSo, we get: $\\Theta(n * n * 64)$ which simplifies into `n^2`\n\n![That's a lot of items to loot...](\u003c../img/assets/image (41).png\u003e)\n{% endtab %}\n{% endtabs %}\n\n{% tabs %}\n{% tab title=\"Question 2b\" %}\nI've tweaked the previous problem a little 😁 Try to spot the difference and see if it changes the runtime at all!\n\n```java\nvoid lootShulkerBoxes(int n, int stacksToLoot) {\n for (int box = n; box \u003e 0; box -= 1) {\n for (int stack = stacksToLoot; stack \u003e 0; stack -= 1) {\n for (int i = 0; i \u003c 64; i += 1) {\n lootItem(i * stack * box);\n }\n }\n } \n}\n```\n{% endtab %}\n\n{% tab title=\"Q2b Answer\" %}\n$\n\\Theta(n)\n$\n\n**Explanation:** Even though `stacksToLoot` is a user input, we're only concerned about finding the runtime for `n` so `stacksToLoot` can be treated like a constant! Therefore, we now have $\\Theta(n * s* 64)$ where `s = stacksToLoot` which simplifies into `n`.\n\n![ok now this is getting a bit overboard](\u003c../img/assets/image (42).png\u003e)\n{% endtab %}\n{% endtabs %}\n\n## Recursion\n\nThe following two problems are inspired by [this worksheet](https://inst.eecs.berkeley.edu/\\~cs61b/sp20/materials/disc/discussion8.pdf).\n\n{% tabs %}\n{% tab title=\"Question 3\" %}\nTREEEEEEEEE recursion 🌳🌲🌴\n\n```java\nvoid plantJungleSaplings(int n) {\n if (n \u003e 0) {\n for (int i = 0; i \u003c 4; i += 1) {\n plantJungleSaplings(n - 1);\n }\n }\n}\n```\n{% endtab %}\n\n{% tab title=\"Q3 Answer\" %}\n$\n\\Theta(4^n)\n$\n\n**Explanation:** This tree recursion creates a tree with `n` layers. Each layer you go down, the number of calls multiplies by 4!\n\n![Tree diagram for method calls.](\u003c../img/assets/image (48).png\u003e)\n\nThis means that the number of calls in total will look like this:\n\n$\n\\sum_{i=1}^{n}4^i\n$\n\nAnd if you remember your power series, you'll know that this sum is equal to $4^{n+1}-1$ which simplifies into the final answer.\n\n![an image that makes you long for TreeCapacitator](\u003c../img/assets/image (49).png\u003e)\n{% endtab %}\n{% endtabs %}\n\n{% tabs %}\n{% tab title=\"Question 4\" %}\nLet's replace the 4 in the previous problem with **n** and see what insanity ensues.\n\n```java\nvoid plantCrazySaplings(int n) {\n if (n \u003e 0) {\n for (int i = 0; i \u003c n; i += 1) { // This line changed\n plantCrazySaplings(n - 1);\n }\n }\n}\n```\n{% endtab %}\n\n{% tab title=\"Q4 Answer\" %}\n$\n\\Theta(n!)\n$\n\n**Explanation:** This tree recursion creates a tree with `n` layers. Each layer you go down, the number of calls multiplies by `n-1`...\n\n![What a mess (!)](\u003c../img/assets/image (51).png\u003e)\n\nThis means that the number of calls in total will look like this:\n\n$\n\\sum_{i=1}^{n} \\frac{n!}{i!}\n$\n\nSince `n!` is not dependent on `i` it can be factored out of the sum to produce this:\n\n$\nn!\\sum_{i=1}^{n} \\frac{1}{i!}\n$\n\nHey, that looks a lot like the Taylor series for $e$! Since `e` is a constant, it simply reduces to `n!`.\n{% endtab %}\n{% endtabs %}\n\n## Best and Worst Case Runtimes\n\n{% tabs %}\n{% tab title=\"Question 5\" %}\nHere's a case where the best case and worst case runtimes are different. Can you figure out what they are? (Let `n = items.length`).\n\n```java\nItem[] hopperSort(Item[] items) {\n int n = arr.length; \n for (int i = 1; i \u003c n; ++i) { \n int key = items[i]; \n int j = i - 1; \n while (j \u003e= 0 \u0026\u0026 items[j].compareTo(key) \u003e 0) { \n items[j + 1] = items[j]; \n j = j - 1; \n } \n items[j + 1] = key; \n } \n}\n```\n{% endtab %}\n\n{% tab title=\"Q5 Answer\" %}\n**Best Case:** $\\Theta(n)$ if the array is nearly sorted except for a couple values. In this case, the `while` loop will only run a small number of times, so the only loop left is the for loop.\n\n**Worst Case:** $\\Theta(n^2)$if the array is totally reversed. This will cause the `while` loop to run on the order of `O(n)` times, resulting in a nested loop.\n\n**Note:** HopperSort is literally just Insertion Sort 😎🤣\n\n![hoppers rate 64/64](\u003c../img/assets/image (45).png\u003e)\n{% endtab %}\n{% endtabs %}\n\n{% tabs %}\n{% tab title=\"Question 6\" %}\nHere's a mutual recursion problem! What are the best and worst cases for `explodeTNT(n)`? What are their runtimes?\n\n```java\nvoid explodeTNT(int n) {\n if (n % 2 == 0) {\n digDirts(n - 1, true);\n digDirts(n - 2, false);\n } else {\n digDirts(n / 2, true);\n }\n}\n\nvoid digDirts(int n, boolean isTNT) {\n if (isTNT) {\n explodeTNT(n / 2);\n }\n removeDirt(); // not implemented, assume O(1) runtime\n}\n```\n{% endtab %}\n\n{% tab title=\"Q6 Answer\" %}\n**Best Case:** $\\Theta(\\log(n))$ if n is even. This will result in n being halved every function call.\n\n**Worst Case:** $\\Theta(n)$if n is odd. See the tree below for an illustration of what happens in this case- hopefully the diagram will make it clearer as to why it's O(n).\n\n![A diagram of what happens in the worst and best cases.](\u003c../img/assets/image (46).png\u003e)\n\n![don't play with tnt, kids](\u003c../img/assets/image (47).png\u003e)\n{% endtab %}\n{% endtabs %}\n\n## Challenge Problems\n\nThese problems are quite difficult. Don't be concerned if you don't feel confident in solving them (I certainly don't).\n\n{% tabs %}\n{% tab title=\"Question 7\" %}\nA huge disaster :ooo\n\n```java\n//initially start is 0, end is arr.length.\npublic int PNH(char[] arr, int start, int end) {\n if (end \u003c= start) {\n return 1;\n }\n int counter = 0; \n int result = 0;\n for (int i = start; i \u003c end; i += 1) {\n if (arr[i] == 'a') {\n counter += 1;\n }\n }\n for (int i = 0; i \u003c counter; i += 1) {\n result += PNH(arr, start + 1, end);\n }\n int mid = start + (end - start) / 2;\n return PNH(arr, start, mid) + PNH(arr, mid + 1, end);\n}\n```\n{% endtab %}\n\n{% tab title=\"Q7 Answer\" %}\n**Best Case:** $\\Theta(n\\log(n))$ If none of the characters in char\\[] is 'a', then each call to PNH does $\\Theta(n)$ work. Total work per layer is always N, with logN layers total.\n\n**Worst Case:** $\\Theta(n!)$ All of characters in char\\[] is 'a'. In this case, the for loop recursive calls will dominate the runtime, because it'll be the main part of the recursive tree. The interval start to end is decreased by one in the for loop recursive calls, while that interval is halved in the return statement recursive calls. This means the return statement recursive calls will reach the base case in logn levels, while the recursive calls in the for loop will take n levels. Thus, we can proceed with the same analysis as question 4.\n{% endtab %}\n{% endtabs %}\n\n{% tabs %}\n{% tab title=\"Question 8\" %}\nCongrats for making it this far! By now you should be an expert in asymptotic analysis :P Here's one last problem:\n\n```java\n//initially start is 0, end is arr.length.\npublic int lastOne(char[] arr, int start, int end) {\n if (end \u003c= start) {\n return 1;\n }\n else if (arr[start] \u003c= arr[end]) {\n return lastOne(arr, start + 1, end - 1);\n } else {\n int temp = arr[start];\n arr[start] = arr[end];\n arr[end] = temp;\n\n return lastOne(arr, start + 1, end) \n + lastOne(arr, start, end - 1) \n + lastOne(arr, start + 1, end - 1);\n }\n}\n```\n{% endtab %}\n\n{% tab title=\"Q8 Answer\" %}\n**Best Case:** $\\Theta(n)$ if the else if case is always true. This will produce a tree with height n/2, where each height does constant work.\n\n**Worst Case:** $\\Theta(3^n)$ if else if case is never true. Sorry no diagram yet :((\n{% endtab %}\n{% endtabs %}\n", + "lastmodified": "2023-01-03T01:48:32.712428766Z", + "tags": null + }, + "/cs61b/misc-topics/exceptions": { + "title": "", + "content": "# Exceptions\n\n## Basics\n\nAn **exception** occurs when something unintended occurs and the interpreter must exit.\n\nWhile this might sound like a bad thing, we can often throw our own exceptions to handle known errors or edge cases more gracefully.\n\n### Exceptions in Java\n\nIn Java, there are two types of exceptions: **checked** and **unchecked.**\n\n**Checked** exceptions are handled during compile time, and are included in the method declaration. As an example:\n\n```java\npublic void openFile() throws IOException {\n ...\n}\n```\n\n* All children that override this method must also throw the same exceptions.\n\n**Unchecked** exceptions are not handled during compile time, and thus are thrown during runtime. All `Error` or `RuntimeException` types are unchecked; all other exceptions are checked. Some examples of unchecked exceptions are dividing by zero (`ArithmeticException`), or accessing an index that doesn't exist (`IndexOutOfBoundsException`).\n\n![Some of the more common Exception types in Java.](\u003c../img/assets/image (4).png\u003e)\n\n## Creating Custom Exceptions\n\nWe can use the `throw` keyword to create exceptions with custom error messages as follows:\n\n```java\npublic void divide(int a, int b) {\n if (b == 0) {\n throw new Exception(\"Error Message\");\n } else {\n return a / b;\n }\n}\n```\n\nThis is often used within a `try catch` block, as such:\n\n```java\npublic void divide2() {\n int a = 0;\n try {\n return 10 / 0;\n } catch(Exception e) {\n System.out.println(\"oops!\");\n }\n }\n```\n\nAn alternate to custom exceptions is to simply handle exception cases. For example, we can add a check to make sure a number is not zero before running a division operation.\n\n## Try/Catch/Finally Example\n\nLet's check your understanding of exception handling!\n\n```java\nstatic String tryCatchFinally() {\n try {\n System.out.println(\"trying\");\n throw new Exception();\n } catch (Exception e) {\n System.out.println(\"catching\");\n return \"done catch\";\n } finally {\n System.out.println(\"finally\");\n }\n }\n```\n\n{% tabs %}\n{% tab title=\"Q1\" %}\nWhat will be printed (and in what order) when `tryCatchFinally()` is run?\n{% endtab %}\n\n{% tab title=\"Q1 Answer\" %}\nFirst, `trying` will be printed.\n\nSince an Exception is thrown, the catch block will run next, so `catching` is printed next.\n\nSince finally blocks _always_ run regardless of result, `finally` is printed last.\n{% endtab %}\n{% endtabs %}\n\n{% tabs %}\n{% tab title=\"Q2\" %}\nSuppose the same code were run, but without the `catch` block. What would this code do?\n\n```java\nstatic String tryFinally() {\n try {\n System.out.println(\"trying\");\n throw new Exception();\n } finally {\n System.out.println(\"finally\");\n }\n}\n```\n{% endtab %}\n\n{% tab title=\"Q2 Answer\" %}\nIf the try block throws an uncaught Exception (i.e. if catch block does not exist or catch block does not handle the type of Exception that is thrown in the try block), Java halts execution of the try block, **executes the finally block**, then raises a runtime error.\\\n\\\nSo, the following sequence would occur:\\\n1\\. `trying` is printed.\\\n2\\. `finally` is printed.\\\n3\\. The program exits with a `RuntimeException`.\n{% endtab %}\n{% endtabs %}\n", + "lastmodified": "2023-01-03T01:48:32.944427554Z", + "tags": null + }, + "/cs61b/misc-topics/modular-arithmetic": { + "title": "", + "content": "# Modular Arithmetic and Bit Manipulation\n\n{% hint style=\"warning\" %}\nMake sure you're comfortable working with binary numbers (adding, subtracting, converting to decimal) before continuing.\n{% endhint %}\n\n## Integer Types\n\nThis is an excerpt from the chart in [Java Objects](../oop/objects.md). Go there to review primitive types first!\n\n| Type | Bits | Signed | Literals |\n| ----- | ---- | ------ | ----------------------------- |\n| byte | 8 | yes | 3, (int)17 |\n| short | 16 | yes | None - must cast from int |\n| char | 16 | no | 'a', '\\n' |\n| int | 32 | yes | 123, 0100 (octal), 0xff (hex) |\n| long | 64 | yes | 123L, 0100L, 0xffL |\n\n## Signed Numbers\n\nA type is **signed** if it can be **positive** **or** **negative.** Unsigned types can _only_ be positive.\n\nIn signed types, the **first bit** is reserved for determining the sign of the number (0 is positive, 1 is negative). This means that there is one fewer bit for the actual number. For example, ints only have **31** bits for the number.\n\n### Reading negative numbers\n\nLet's say you are given a number like `10100`and want to convert it to decimal. We know that the 1 in the front means it's a negative number! However, we can't just discard that 1 and read the rest like a positive number. Instead, we have to **flip all the bits** and then **add one** to the result. So, `10100` flipped will become `01011`. Adding one will result in `01100`, which is the correct answer (12).\n\n**Why do we have to do this?** Read on to the next section to find out!\n\n## Two's Complement\n\n**Two's Complement** is a a method of storing negative numbers in a way that supports proper arithmetic. Here's how it works:\n\n1. Start with a binary number we want to negate, like `0101`, which is 5.\n2. Flip all the bits to make `1010`.\n3. Add one to make `1011`.\n\nAlthough it makes negative numbers harder to read, the benefits are much more significant- it allows addition and subtraction to work between positive and negative numbers.\n\nIf you want to see firsthand why simply flipping the signed bit doesn't work, try out some problems in [this worksheet](https://d1b10bmlvqabco.cloudfront.net/attach/k5eevxebzpj25b/jcaul3qcivh6kh/k8g51ayfl9ui/GuerillaSection2.pdf) ([solutions](https://d1b10bmlvqabco.cloudfront.net/attach/k5eevxebzpj25b/jcaul3qcivh6kh/k8g53zthgevk/GuerillaSection2Sols.pdf)).\n\n## Modular Arithmetic\n\nSince primitive types have a fixed number of bits, it is possible to **overflow** them if we add numbers that are too large. For example, if we add `01000000`(a byte) with itself, we'd need 9 bits to store the result!\n\nThis will cause lots of issues, so we use **modular arithmetic** to **wrap around to the largest negative version** and keep the number in bounds. For example, `(byte)128 == (byte)(127+1) == (byte)(-128)`**.**\n\n## Bit Operations\n\n**Mask: \u0026**\n\n* `A \u0026 B` will only keep the bits that are 1 in A **AND** B\n* Example: `00101100 \u0026 10100111 == 00100100`\n\n**Set: |**\n\n* `A | B` will keep the bits that are 1 in A **OR** B\n* Example: `00101100 | 10100111 == 10101111`\n\n**Flip: ^**\n\n* `A ^ B` will keep the bits that are 1 in A **XOR** B\n* In other words, 1 if bits are unequal in A and B, 0 otherwise\n* Example: `00101100 ^ 10100111 == 10001011`\n\n**Flip all: \\~**\n\n* `~A` will flip all the bits from 1 to 0 or 0 to 1 in A\n* Example: `~10100111 == 01011000`\n\n**Shift Left: \u003c\u003c**\n\n* `A \u003c\u003c n` will shift all bits left n places\n* All newly introduced bits are 0\n* Example: `10101101 \u003c\u003c 3 == 01001000`\n* `x \u003c\u003c n` is equal to x \\* 2^n\n\n**Arithmetic Right: \u003e\u003e**\n\n* `A \u003e\u003e n` will shift all bits **except for the signed bit** right n times\n* Newly introduced bits are the same as the signed bit\n* Example: `10101101 \u003e\u003e 3 == 11110101`\n\n**Logical Right: \u003e\u003e\u003e**\n\n* `A \u003e\u003e\u003e n` will shift ALL bits right n times\n* Newly introduced bits are 0\n* Example: `10101101 \u003e\u003e\u003e 3 == 00010101`\n* Another example: `(-1) \u003e\u003e\u003e 29 == 7` because it leaves 3 1-bits- ints are 32 bits\n\n## Why is this useful?\n\nJust looking at these obscure operations, it may be unclear as to why we need to use these at all.\n\nWell, [here's a massive list of bit twiddling hacks](https://graphics.stanford.edu/\\~seander/bithacks.html) that should demonstrate plenty of ways to use these simple operations to do some things really efficiently.\n\nThese operations are also the **building blocks for almost all operations done by a computer.** You'll see firsthand how these are used to construct ALU's in [61C](https://cs61c.org/).\n", + "lastmodified": "2023-01-03T01:48:32.948427532Z", + "tags": null + }, + "/cs61b/misc-topics/more-resources": { + "title": "", + "content": "# More Resources\n\nHere are some more cool things to look at!\n\n* [Big O Cheat Sheet ](https://www.bigocheatsheet.com/)- complexities of sorting and common data structure operations\n* [Toptal Sorting Algorithm Animations ](https://www.toptal.com/developers/sorting-algorithms)- animations, pseudocode, and property summaries\n* [Josh Hug's 61B Playlist](https://www.youtube.com/channel/UC7FzTMO4rKvlqIyU5vwzFKQ/playlists) - concise video lectures for most 61B topics\n* [Balanced Search Demos](https://inst.eecs.berkeley.edu/\\~cs61b/sp20/materials/lectures/lect29/) - play around with balanced search structures and see how they work\n", + "lastmodified": "2023-01-03T01:48:32.948427532Z", + "tags": null + }, + "/cs61b/oop/access-control": { + "title": "", + "content": "# Access Control\n\n## What is Access Control?\n\nIn Java, we can specify the **level of access** certain variables and methods have. With this power, we can show or hide these variables to other classes and references on demand!\n\nThere are **4** modifier levels that get progressively more open:\n\n* **Private:** Only this class can see it.\n* **Package Protected (the default level):** All classes in the **same package** can see it.\n* **Protected: Subclasses** (that inherit from the parent) can also see it.\n* **Public:** All classes in the program can see it.\n\n![A chart comparing the different access modifiers. The black bar is the default (\"package protected\").](\u003c../img/assets/image (5).png\u003e)\n\n## Why do we need access control?\n\nAccess control works really well with other OOP concepts to help structure programs better and make them easier to understand. Here are some of the major benefits:\n\n* Access control is **self documenting.** Usually, there's a reason for making certain variables private and others public, and no more needs to be said for that to be understood.\n* **It's safe to change private methods without worrying about breaking things.** If a method is private, we know that the only references are within the same class, so we can edit them however we want without making other classes error as well.\n* **Private/protected variables don't need to be understood by users.** If someone needs to use your program, they don't need to learn how to use any private methods since those will be hidden to them.\n\n## Practice\n\nLet's see how access control can be used to hide variables in different situations:\n\n```java\npackage P;\npublic class A {\n int def; // Variable with default access\n protected int prot; // Variable with protected access\n private int priv; // Variable with private access\n \n static class NestedA { ... }\n}\n\npublic class B extends A { ... }\n\n===================\npackage Q;\npublic class C extends P.A { ... }\n\n```\n\n{% tabs %}\n{% tab title=\"Question 1\" %}\nWhich variables can be accessed in B?\n{% endtab %}\n\n{% tab title=\"Answer\" %}\n`def` and `prot` since B is in the same package as A.\n{% endtab %}\n{% endtabs %}\n\n{% tabs %}\n{% tab title=\"Question 2\" %}\nWhich variables can be accessed in C?\n{% endtab %}\n\n{% tab title=\"Answer\" %}\n`prot` only, since C is in a different package but extends A.\n{% endtab %}\n{% endtabs %}\n\n{% tabs %}\n{% tab title=\"Question 3\" %}\nWhich variables can be accessed in NestedA?\n{% endtab %}\n\n{% tab title=\"Answer\" %}\nNone of them, because NestedA is static and cannot reference any non-static variables.\n{% endtab %}\n{% endtabs %}\n", + "lastmodified": "2023-01-03T01:48:32.948427532Z", + "tags": null + }, + "/cs61b/oop/dynamic-method-selection": { + "title": "", + "content": "\n# Dynamic Method Selection\n\n{% hint style=\"warning\" %}\nThis is a **very tricky topic**. Make sure you are comfortable with [inheritance](inheritance.md) and [access control ](access-control.md)before proceeding!\n{% endhint %}\n\nInheritance is great and all, but it does have some issues. One of the biggest issues lies in overriding: **if two methods have exactly the same name and signature, which one do we call?**\n\nIn a standard use case, this is a pretty simple answer: whichever one is in the class we want! Let's look at some basic examples.\n\n```java\npublic class Dog {\n public void eat() { ... } // A\n}\n\npublic class Shiba extends Dog {\n @Override\n public void eat() { ... } // C\n}\n```\n\n{% tabs %}\n{% tab title=\"Question 1\" %}\nWhich method is called when we run**:**\n\n```java\nDog rarePupper = new Dog();\nrarePupper.eat();\n```\n{% endtab %}\n\n{% tab title=\"Q1 Answer\" %}\nIt's **A** :dog: Dog doesn't know anything about `Shiba` or any other classes, so we can just look at the Dog.\n{% endtab %}\n{% endtabs %}\n\n{% tabs %}\n{% tab title=\"Question 2\" %}\nWhat about when we call:\n\n```java\nShiba doge = new Shiba();\nrarePupper.eat();\n```\n{% endtab %}\n\n{% tab title=\"Q2 Answer\" %}\nThis calls **C**! This works intuitively because `Shiba` overrides `Dog` so all `Shibas` will use C instead of A.\n\n![](\u003c../img/assets/image (8).png\u003e)\n{% endtab %}\n{% endtabs %}\n\n## Things Get Wonky: Mismatched Types\n\nThere's an interesting case that actually works in Java:\n\n```java\nDog confuzzled = new Shiba();\n```\n\nWhat??? Shouldn't this error because `Dog` is incompatible with `Shiba`?\n\nIt turns out that **subclasses can be assigned to superclasses.** In other words, `Parent p = new Child()` works fine. This is really useful for things like [Interfaces](inheritance.md#interfaces) and generic [Collections](../abstract-data-types/collections/) because we might only care about using generic methods, and not the specific implementation that users chose to provide.\n\nHowever, **it is important to note that it doesn't work the other way.** `Child c = new Parent()` will error because the child might have new methods that don't exist in the parent.\n\n**Let's see how this makes inheritance really tricky:**\n\n```java\n/** The following problems are inspired by Spring 2020 Exam Prep 5. */\n\npublic class Dog {\n public void playWith(Dog d) { ... } // D\n}\n\npublic class Shiba extends Dog {\n @Override\n public void playWith(Dog d) { ... } // E\n public void playWith(Shiba s) { ... } // F\n}\n```\n\n{% tabs %}\n{% tab title=\"Question 3\" %}\nWhich method(s) run when we call:\n\n```java\nDog rarePupper = new Shiba();\nrarePupper.playWith(rarePupper); // aww rarePupper is lonely :(\n```\n{% endtab %}\n\n{% tab title=\"Q3 Answer\" %}\n**E** is called! What happens is that the **dynamic type** is chosen to **select the method from,** but the **static type** is used to **select the parameters.** `rarePupper`'s **** dynamic type is `Shiba` but its static type is `Dog` so `Shiba.playWith(Dog)` is chosen as the method.\n\n![rarePupper in action](\u003c../img/assets/image (10).png\u003e)\n{% endtab %}\n{% endtabs %}\n\n{% tabs %}\n{% tab title=\"Question 4\" %}\nWhich is called when we run**:**\n\n```java\nDog rarePupper = new Shiba();\nShiba doge = new Shiba();\nrarePupper.playWith(doge); // rarePupper is happy :) borks all around\n```\n{% endtab %}\n\n{% tab title=\"Q4 Answer\" %}\n**E** is called again! Bet ya didn't see that coming 😎\n\n**Why is it not F? I thought doge and rarePupper were both** `Shiba`**?**\\\n****When the compiler chooses a method, it **always** starts at the **static method.** Then, it keeps going down the inheritance tree until it hits the **dynamic method.** Since F has a **different signature** than D, it isn't an **overriding method** and thus the compiler won't see it. But E is (since it has the same signature as D), so that is why it is chosen instead.\n\n![bork bork bork :DDD](\u003c../img/assets/image (11).png\u003e)\n{% endtab %}\n{% endtabs %}\n\n## Adding more insanity: Static vs. Dynamic\n\nBy now, you should have a pretty good understanding of the **method selection** part of DMS. But why is it **dynamic?**\n\nYou may have noticed that there are **two** type specifiers in an instantiation. For example, `Dog s = new Shiba()` has type `Dog` on the left and `Shiba` on the right.\n\nHere, `Dog` is the **static type** of `s`: it's what the compiler believes the type should be when the program is compiled. Since the program hasn't run yet, Java doesn't know what exactly it is- it just knows it has to be some type of `Dog`.\n\nConversely, `Shiba` is the **dynamic type:** it gets assigned during runtime.\n\n### The type rules\n\nJust remember: **like chooses like.** If a method is **static**, then choose the method from the **static type.** Likewise, if a method is **not static,** choose the corresponding method from the **dynamic type.**\n\nLet's try some examples!\n\n```java\npublic class Dog {\n public static String getType() {\n return \"cute doggo\";\n \n @Override // Remember, all objects extend Object class! \n public String toString() {\n return getType();\n }\n}\n\npublic class Shiba extends Dog {\n public static String getType() {\n return \"shiba inu\";\n }\n}\n```\n\n{% tabs %}\n{% tab title=\"Question 5\" %}\nWhat prints out when we run:\n\n```java\nDog d = new Shiba();\nSystem.out.println(d.getType());\n```\n{% endtab %}\n\n{% tab title=\"Q5 Answer\" %}\n`cute doggo` gets printed because `getType()` is a static method! Therefore, Java looks at the **static type** of `d`, which is `Dog`. \\\n(If `getType()` weren't static, then `shiba inu` would have been printed as usual.)\n{% endtab %}\n{% endtabs %}\n\n{% tabs %}\n{% tab title=\"Question 6\" %}\nWhat prints out when we run:\n\n```java\nShiba s = new Shiba();\nSystem.out.println(s);\n```\n{% endtab %}\n\n{% tab title=\"Q6 Answer\" %}\n`cute doggo` also gets printed!! This is because static methods **cannot be overridden.** When `toString()` is called in `Dog`, it doesn't choose `Shiba`'s `getType()` because `getType()` is static and the static type is `Dog`.\n{% endtab %}\n{% endtabs %}\n\n{% tabs %}\n{% tab title=\"Question 7\" %}\nWhat prints out when we run:\n\n```java\nDog d = new Shiba();\nSystem.out.println(((Shiba)d).getType());\n```\n{% endtab %}\n\n{% tab title=\"Q7 Answer\" %}\nThis time, `shiba inu` gets printed. This is because casting temporarily changes the **static type:** since the static type of `d` is **** `Shiba` in line 2, it chooses the `getType()` from `Shiba`.\n{% endtab %}\n{% endtabs %}\n\n## That's all, folks!\n\nIf you want some **even harder** problems, [check this out](https://inst.eecs.berkeley.edu/\\~cs61b/sp20/materials/disc/examprep5.pdf) and also [this](https://inst.eecs.berkeley.edu/\\~cs61b/sp20/materials/disc/examprep6.pdf).\n\n![bai bai!](\u003c../img/assets/image (12).png\u003e)\n", + "lastmodified": "2023-01-03T01:48:32.948427532Z", + "tags": null + }, + "/cs61b/oop/generics": { + "title": "", + "content": "# Generic Types\n\nSometimes, we want things to support **any type**, including user defined types that we don't know about! For example, it would make sense that we don't care what type we make a `List` out of, since it's just a whole bunch of objects put together.\n\nThe Java solution is **generics!** Generic types are denoted by a `\u003c\u003e` and can be appended to **methods and classes.** Here's an example with classes:\n\n```java\n/**\n * Creates a type SomeClass that takes * in a generic SomeType. SomeType can * be named anything.\n*/\npublic class SomeClass\u003cSomeType\u003e {\n private SomeType someThing;\n\n public void someMethod(SomeType stuff) {\n doStuff(stuff);\n }\n}\n\n...\n/** Creates a new instance of SomeClass, setting SomeType to String.\n We don't need to put the type on the right since it's already\n defined on the left. */\nSomeClass\u003cString\u003e aClass = new SomeClass\u003c\u003e();\n```\n\nIn this example, `SomeType` is a **Generic Type Variable** that is not a real type, but can still be used inside the class as normal.\n\nOn the other hand, `String` is an **Actual Type Argument** that replaces `SomeType` during runtime. Now, every time `SomeType` is used in `SomeClass` Java treats it exactly like a `String`.\n\n## Generic Subtypes\n\nLike in _\\*\\*_[Dynamic Method Selection](dynamic-method-selection.md), adding inheritance makes things tricky! Let's look at an example:\n\n```java\nList\u003cString\u003e LS = new ArrayList\u003cString\u003e();\nList\u003cObject\u003e LO = LS; // Line 3\nLO.add(42); // Line 4\nString s = LS.get(0); // Line 5\n```\n\n{% tabs %}\n{% tab title=\"Question 1\" %}\nWill **line 3** error?\n{% endtab %}\n\n{% tab title=\"Q1 Answer\" %}\n**No**, line 3 is valid and will not error! This is because Object is a **superclass** of String. Generics work in a very similar way to the [inheritance rules](inheritance.md).\n{% endtab %}\n{% endtabs %}\n\n{% tabs %}\n{% tab title=\"Question 2\" %}\nWill **line 4** error?\n{% endtab %}\n\n{% tab title=\"Q2 Answer\" %}\n**No**, line 4 is valid and will not error! This is because LO is a **list of Objects** and integers are a **subtype** of Object, as all things are.\n{% endtab %}\n{% endtabs %}\n\n{% tabs %}\n{% tab title=\"Question 3\" %}\nWill **line 5** error?\n{% endtab %}\n\n{% tab title=\"Q3 Answer\" %}\n**Yes,** line 5 will error! This is because we put 42 into LO, which is an integer. Since LO is pointing to the same object as LS, 42 is also in LS! That means we are trying to assign a String equal to an integer.\n{% endtab %}\n{% endtabs %}\n\n{% hint style=\"info\" %}\nArrays have slightly different behavior than this and will throw an `ArrayStoreException` if types are mismatched in any way.\n{% endhint %}\n\n## Type Bounds\n\nSometimes, we want to **put constraints** on what kinds of types can be passed into a generic type.\n\nOne way of doing is is to specify that a generic type must fit within a **type bound**: here, T must be some subtype of a specified type `Number`.\n\nWe can also do it the other way and specify that a type can be a **supertype** of a specified type. Both of these examples are shown below:\n\n```java\nclass SomeClass\u003cT extends Number\u003e {\n // A method that takes a type parameter T and takes any SUPERCLASS\n // of T as a list generic type.\n static \u003cT\u003e void doSomething(List\u003c? super T\u003e L) { ... }\n}\n```\n\n## Limitations of Generic Types\n\nThe biggest limitation is that **primitive types cannot be used as generic types.** For example, `List\u003cint\u003e` is invalid and will not work!\n\nOne workaround to this is to use the reference-type counterparts to primitives, such as `Integer`, `Boolean`, `Character` and so on. However, converting between these types and primitive types, which is called **autoboxing,** has significant performance penalties that must be taken into consideration.\n\nAnother limitation is that **instanceof** does not work properly with generic types. For instance, `new List\u003cX\u003e() instanceof List\u003cY\u003e` will always be true regardless of what types X and Y are.\n", + "lastmodified": "2023-01-03T01:48:32.948427532Z", + "tags": null + }, + "/cs61b/oop/inheritance": { + "title": "", + "content": "# Inheritance\n\n## What is inheritance?\n\nEssentially, it's a way of putting similar objects together to **generalize behavior.** Inheritance is best used with relating **subtypes** to larger categories. For example, an :tangerine:orange **is a** fruit (so it's a **subtype** of fruit).\n\nLet's say that a supermarket named _Jrader Toe's_ asks us to simulate fruits for them in an online system. We could do it like this:\n\n![The naive approach.](../img/assets/image.png)\n\nNow, every fruit would need some of the same properties- like cost, weight, and name! So we would need to do something like:\n\n```java\npublic class Orange {\n private String name = \"Orange\";\n private int cost;\n ...\n public Orange(int cost, ...) {\n this.cost = cost;\n ...\n }\n // lots of methods\n public String getName() { ...\n```\n\nThis would be _really annoying_ to do for every single fruit. And they're all the same properties for every fruit so it would also be incredibly inefficient code-wise. **Inheritance gives a much better solution!**\n\nLet's make a **Fruit** class and have all of our fruits **inherit from** that class.\n\n![uwu inheritance is cool and good](\u003c../img/assets/image (1).png\u003e)\n\nThis does amazing things because we can just create one single Fruit class that has all of the properties we need, and simply make our specific fruits inherit those properties. (Side note: making multiple things inherit from one generic interface like this is called **polymorphism.**)\n\n```java\npublic class Fruit {\n private String name;\n private int cost;\n ...\n public Orange(String name, int cost, ...) {\n this.name = name;\n this.cost = cost;\n ...\n }\n // lots of methods\n public String getName() { ...\n}\n\n// Now for a very simple Orange method!\npublic class Orange extends Fruit {\n public Orange(int cost,...) {\n super(\"Orange\", cost, ...);\n }\n}\n```\n\nWith only those 4 lines, :tangerine:Orange now has all of the same methods and properties that Fruit has!\n\n## Implementation Inheritance (\"Extends\")\n\nYou may have noticed the `extends` keyword being used to specify that an object **inherits** from another object. This is called **implementation inheritance** since an object takes all of the behaviors from its parent and can use them like its own.\n\nWhen `extends` is used, these are the things that are inherited:\n\n* All instance and static variables that are **not private** (see [Access Control](access-control.md) for more information)\n* All non-private methods\n* All nested classes\n\nThese are **not** inherited:\n\n* Any **private** variables and methods\n* All constructors\n\n{% hint style=\"info\" %}\n**Quick sidenote!**\\\n****All objects automatically extend the `Object` class whether you like it or not. See [References, Objects, and Types in Java](objects.md) **** for more about this behavior.\n{% endhint %}\n\n### Constructor magic 🏗\n\nWhen an object `extends` another object, its constructor will **automatically call the parent's constructor.** However, this does have some limitations:\n\n* It will only call the **default** (no-argument) constructor in the parent.\n* Calling the constructor is the **first thing that is done** in the child constructor.\n\nBut what if we want to call another constructor? That's where the `super` keyword comes in! When `super` is called, Java will know to **not** call the default constructor anymore. Here's an example:\n\n```java\npublic class Parent {\n public Parent() {\n System.out.println(\"Default constructor\");\n }\n public Parent(String say) {\n System.out.println(say);\n }\n void doStuff() { ... }\n}\n\n// Child inherits doStuff(), but not the constructors.\npublic class Child extends Parent {\n public Child() {\n System.out.println(\"Child\")\n }\n public Child(String say) {\n super(say);\n }\n}\n \npublic static void Main(String[] args) {\n Child c1 = new Child(); // will print \"Default constructor\" then \"Child\" !!!\n Child c2 = new Child(\"Hi\"); // will print \"Hi\"\n}\n```\n\n## Method Overriding\n\nLet's say that _Jrader Toe's_ is running a promotion for 🍐pears and wants to make them 20% off normal pears! This poses a problem because **we want to inherit everything that normal pears have, but change only one behavior** (getPrice). Well I've got the solution for you!!! And it's called **overriding.**\n\n```java\npublic class PromoPear extends Pear {\n public PromoPear(int cost, ...) {\n super(cost, ...);\n }\n \n // Overriding the getPrice to have a new behavior only for PromoPears!\n @Override\n public int getPrice() {\n return super.getPrice() * 0.8;\n }\n ...\n} \n```\n\nThe `@Override` tag is technically optional, but it's highly suggested because it makes sure that you are indeed overriding something and not just making a new method! (Remember, it has to have the **same name and parameters as a method in one of its parents**.)\n\n## **Method Overloading**\n\nSometimes, you want to take in **different parameters** into the **same method.** For instance, what if we wanted to create a method `getCount(Fruit fruit)` that counts how many fruits of that type we have? We might also want to allow users to pass in the name of the fruit to do the same thing- `getCount(String fruit)`. Java will allow us to make **both** of these methods in the same class!\n\nHowever, this has some major downsides that should be considered.\n\n* It's repetitive.\n* It requires maintaining more code- changing one overload won't change the others!\n* You can't handle any data types other than the ones you explicitly specify will work.\n\nWe'll discuss better solutions further down the page as well as in the [Generic Types](generics.md) page!\n\n### How is overriding different from overloading?\n\nThey have very similar names but pretty different uses!\n\nOverriding is for methods of the same name, **same parameters**, and **different classes.** If you can remember when you use the `@Override` tag, you can relate it back to this concept!\n\nOverloading is for methods of the same name, **different parameters**, in the **same class**.\n\n## Interfaces\n\nInterfaces are like **blueprints 📘** for objects- they tell you what an object needs, but not how to implement them.\n\nThey are very similar to normal classes except for some major differences:\n\n* **All variables are constants** (public static final).\n* **Methods have no body**- just a signature (like `void doStuff();`)\n* **Classes can inherit from multiple interfaces.**\n\nTypically, interfaces will not have any implemented methods whatsoever. This limitation can technically be removed using the [default keyword](https://stackoverflow.com/questions/31578427/what-is-the-purpose-of-the-default-keyword-in-java/31579210), but this is **not recommended** because abstract classes handle this much better.\n\nHere's an example of interfaces in the wild:\n\n```java\npublic interface AnInterface\u003cItem\u003e {\n public void doStuff(Item x);\n public Item getItem();\n ...\n}\n\npublic class Something implements AnInterface\u003cItem\u003e { // Note the IMPLEMENTS!\n @Override\n public void doStuff(Item x) {\n // implement method\n }\n\n @Override\n public void getItem() {\n // implement method\n }\n}\n\npublic class MainClass {\n public static void main(String[] args) {\n AnInterface\u003cString\u003e smth = new AnInterface\u003c\u003e(); // ERROR!!\n // (new can't be used with interfaces.)\n AnInterface\u003cString\u003e smthElse = new Something\u003cString\u003e(); // Will not error!\n smth.getItem();\n ...\n }\n}\n```\n\n## Abstract Classes\n\nAbstract classes live in the place **in between** interfaces and concrete classes. In a way, they get the best of both worlds- you can implement whichever methods you want, and leave the rest as **abstract** methods (same behavior as interface methods)!\n\nHere are some properties:\n\n* **Variables behave just like a concrete class.**\n* **Normal methods can be created like any other concrete class.**\n* **Abstract methods** (`abstract void doSomething()`) **behave just like methods in interfaces.**\n* Classes can only inherit from **one** abstract class.\n\nHere's the same example from the interfaces section, but implemented using an abstract class.\n\n```java\npublic abstract class AnAbstract\u003cItem\u003e {\n public abstract void doStuff(Item x);\n public abstract Item getItem();\n ...\n}\n\npublic class Something extends AnAbstract\u003cItem\u003e { // EXTENDS, not implements!\n @Override\n public void doStuff(Item x) {\n // implement method\n }\n\n @Override\n public void getItem() {\n // implement method\n }\n}\n\npublic class MainClass {\n public static void main(String[] args) {\n AnAbstract\u003cString\u003e smth = new AnAbstract\u003c\u003e(); // ERROR!!\n // (new can't be used with abstract classes, just like interfaces.)\n AnAbstract\u003cString\u003e smthElse = new Something\u003cString\u003e(); // Will not error!\n smth.getItem();\n ...\n }\n}\n```\n\n![A chart comparing the differences between the types of classes.](\u003c../img/assets/image (2).png\u003e)\n\n## Still not satisfied?\n\nWatch [Josh Hug's video lecture](https://www.youtube.com/watch?v=IaEq\\_fogI08\\\u0026list=PL8FaHk7qbOD6km6LlaHLWgRl9SbhlTHk2) about inheritance.\n\nOr, move onto an advanced application of inheritance concepts, [Dynamic Method Selection](dynamic-method-selection.md).\n", + "lastmodified": "2023-01-03T01:48:32.948427532Z", + "tags": null + }, + "/cs61b/oop/objects": { + "title": "", + "content": "# Java Objects\n\nThere are two main categories of objects in Java: **Primitive Types** and **Reference Types.** This page will give a brief overview of both, and close off with some info about the mystical **Object** class.\n\n## Primitive Types\n\n**Primitive types** are built in to Java and have **fixed memory sizes.** Different types require different amounts of memory.\n\nIf you remember [environment diagrams](http://albertwu.org/cs61a/notes/environments), you may recall that some variables are put straight into the boxes, while others have an arrow pointing to them. The reason for this is that it actually denotes primitive vs. reference types! **Primitive types go straight in the box** because they aren't mutable (i.e. you can't change the objects contained in the box since they're just constant literals like numbers).\n\n**There are 8 primitive types in Java.** Here's a table of their properties! (If you don't know what \"signed\" means, go to [Modular Arithmetic and Bit Manipulation](../misc-topics/modular-arithmetic.md).)\n\n| Type | Bits | Signed | Default | Examples |\n| ------- | ---- | ------ | ------- | ----------------------------- |\n| boolean | 1 | no | false | true, false |\n| byte | 8 | yes | 0 | 3, (int)17 |\n| short | 16 | yes | 0 | None - must cast from int |\n| char | 16 | no | \\u0000 | 'a', '\\n' |\n| int | 32 | yes | 0 | 123, 0100 (octal), 0xff (hex) |\n| long | 64 | yes | 0 | 123L, 0100L, 0xffL |\n| float | 32 | yes | 0.0 | 1.23f, -1.23e10f, .001f |\n| double | 64 | yes | 0.0 | 1.23e256d, 1e1d, 1.2e-10d |\n\n{% hint style=\"info\" %}\n**A quick aside on Strings 🧵**\\\nYou may have noticed that strings are not on this list. That is because unlike in Python, they aren't a primitive type! Under the hood, Strings are a reference type that are very similar to a char array.\n{% endhint %}\n\n## Type Conversion\n\nJava will automatically convert between primitive types if **no information is lost** (\nfrom byte to int).\n\nConversion in the other direction (from a larger to smaller container) requires an explicit cast (e.g., `(char) int`). The compiler will treat a cast object as though its static type is the cast type, but this will only work if the cast type is the same as or a parent of the dynamic type. However, relative to the assigned static type, the cast type could be a child of the static type or a parent of the static type.\n\n**Assignment statements are an exception to this**: `aByte = 10` is fine even though 10 is an int literal. This is because arithmetic operations (+, \\*, ...) automatically promote operands (e.g., `'A' + 2` is equivalent to `(int)'A' + 2`)\n\nHowever, **this doesn't work if you are trying to add a larger type to a smaller type** (e.g., `aByte = aByte + 1` since operands become an int type which cannot be set equal to a byte type. **But += works**!\n\n## Reference Types\n\nA **reference type** refers to basically anything that's not primitive 😅\n\nThis includes **user-defined objects** as well as many common Java built-in types such as **arrays, strings, and** [**collections**](../abstract-data-types/collections/)**.**\n\nHere are some major differences that set them apart from primitive types:\n\n* Reference types can take an **arbitrary amount of memory.** Unlike primitives which have a fixed memory for each type, objects like arrays can expand to hold lots of things inside it.\n* Reference types are referred to using **addresses.** When you say something like `int[] arr = new int[5]`, `arr` only stores a 64-bit **memory address** which **points** to the real object, a 5-length integer array. Again, think back to the arrow in environment diagrams, and how those work.\n* By default, reference types can be set to **null** which is represented as an **address of all zeroes.** Or, the **new** keyword can be used to set it to a specific address.\n* Reference objects can be **lost** if all pointers to it are reassigned. For example, if I now enter `arr = null;`, the original 5-length array still exists, but just has nothing to refer to it.\n\n## The Equals Sign\n\nThe assignment operator (`=`) has **different behaviors** for primitive types and references types.\n\nFor **primitive types,** `y = x` means \"**copy** **the bits** from y into a new location, then call them x\". Here, the **entire object** is copied- this means that changing y will NOT change x even though they are set \"equal\".\n\nFor **reference types,** `obj1 = obj2` means \"**copy the address** stored in obj1 to obj2\". Here, `obj1` and `obj2` are referring to the **exact same object,** and mutating one will change the other.\n\n{% hint style=\"info\" %}\n**A clarification on reference type assignment**\n\nBy mutating, I mean changing the **internals** of an object (for example, accessing an array index or doing something like `obj1.value = 1`. If you change the actual **address** of `obj2`, as in `obj2 = obj3`, this does **not** change `obj1` because `obj2` is now referring to a completely different object!\n{% endhint %}\n\n## The Object Class\n\nIn Java, **all objects inherit from the master Object class.** Here are some important properties of Object that will be useful to know:\n\n* `String toString()`: By default, this prints out the class name followed by the memory address (e.g., `Object@192c38f`). This can be overridden to make more user-friendly names for objects.\n* `boolean equals(Object obj)`: By default, this checks if the two objects are actually the same object (same memory address). This can be overridden to check if specific contents of objects are the same, rather than checking if they are literally the same object. (Like `\"foo\"` should equal `new String(\"foo\")`)\n* `int hashCode()`: Returns a numeric hash code for the object that should differentiate it from other objects. **This should be overridden if** **`equals()` is overridden** since `x.hashCode()` should equal `y.hashCode()` if `x.equals(y)` is true!\n* `Class\u003c?\u003e getClass()`: Returns the class of this object.\n\nObject has plenty of other methods and properties as well, but these aren't as important. If you want to learn about them, feel free to refer to the [Java documentation](https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html).\n", + "lastmodified": "2023-01-03T01:48:32.952427512Z", + "tags": null + }, + "/cs61b/sorting/sorting-basics": { + "title": "", + "content": "# Sorting\n\n{% hint style=\"info\" %}\nFor more information about specific sorting algorithms covered in 61B, see my [guide on sorting](https://docs.google.com/document/d/1dUfzdh5V3okrwFbB9o0PgtEBaLHyCqJFwpQWyQ53IeU/edit) that covers all of the sorts in far greater detail 🙂\n{% endhint %}\n\n## Why sort?\n\n* It makes searching for a specific value much faster (e.g. binary search). Typically, searching through an unsorted list requires a full scan ($\\Theta(N)$​ runtime).\n* It's easy to see if two items in list are equal: just compare to see if any neighboring values are the same.\n\n## Properties of a Sorting Algorithm\n\nA sorting algorithm changes a sequence based on a **total order.** A total order is:\n\n* **Total:** All items can be compared with one another\n* **Reflexive:** An item can be compared to itself\n* **Antisymmetric:** x \u003c= y AND y \u003c= x IFF y == x\n* **Transitive:** If x \u003c= y and y \u003c= z, then x must be \u003c= z\n\nA sorting algorithm could be **stable** if it does not change relative order of equivalent entries. For example, if Bob and I both owned Toyota Corollas, and the list of cars were sorted by model, if Bob's car came before mine originally it must also come before mine in the sorted list after a stable sort.\n\n\n\n## Sorting Algorithm Classifications\n\n* **Internal sort:** Keeps all data in primary memory\n* vs. **External sort:** Processes data in batches, then merges them together at the end\n* **Comparison-based sort:** The only thing we know about keys are their relative orders\n* **Radix sort:** Uses information other than keys\n* **Insertion sort:** Insert items at their appropriate positions one at a time\n* **Selection sort:** Chooses items and places them in order\n\n## Sorting in Java\n\nJava automatically chooses the best sorting algorithm for a given list if you call the `Arrays.sort` method.\n\n```java\nString[] x = new String[] {\"Vat\", \"Bat\", \"Cat\"};\n\nArrays.sort(x); // mutates x into Bat, Cat, Vat\nArrays.sort(x, Collections.reverseOrder()); // mutates x into Vat, Cat, Bat\nArrays.sort(x, 0, 2) // sorts the first two elements, leaving the rest unchanged (Cat, Vat, Bat)\n```\n\n## Inversions\n\nInversions are used as a measure for how sorted a list is. For every two elements that are swapped compared to a sorted list, we add one inversion.\n\n* As an example, if `1 2 3 4 5` is a sorted list, `1 4 3 2 5` would have one inversion (`4` and `2` are swapped).\n* 0 inversions mean a list is perfectly sorted.\n* In the worst case, a reversed list will have $(N \\cdot (N-1))/2$ inversions.\n\n## The Guide to Sorting Algorithms\n\n[A comprehensive guide to sorting algorithms, now with memes!](https://docs.google.com/document/d/1dUfzdh5V3okrwFbB9o0PgtEBaLHyCqJFwpQWyQ53IeU/edit)\n", + "lastmodified": "2023-01-03T01:48:32.952427512Z", + "tags": null + }, + "/example/": { + "title": "Example Site", + "content": "\n# Introduction\n\n## Ferre hinnitibus erat accipitrem dixi Troiae tollens\n\nLorem markdownum, a quoque nutu est *quodcumque mandasset* veluti. Passim\ninportuna totidemque nympha fert; repetens pendent, poenarum guttura sed vacet\nnon, mortali undas. Omnis pharetramque gramen portentificisque membris servatum\nnovabis fallit de nubibus atque silvas mihi. **Dixit repetitaque Quid**; verrit\nlonga; sententia [mandat](http://pastor-ad.io/questussilvas) quascumque nescio\nsolebat [litore](http://lacrimas-ab.net/); noctes. *Hostem haerentem* circuit\n[plenaque tamen](http://www.sine.io/in).\n\n- Pedum ne indigenae finire invergens carpebat\n- Velit posses summoque\n- De fumos illa foret\n\n## Est simul fameque tauri qua ad\n\nLocum nullus nisi vomentes. Ab Persea sermone vela, miratur aratro; eandem\nArgolicas gener.\n\n## Me sol\n\nNec dis certa fuit socer, Nonacria **dies** manet tacitaque sibi? Sucis est\niactata Castrumque iudex, et iactato quoque terraeque es tandem et maternos\nvittis. Lumina litus bene poenamque animos callem ne tuas in leones illam dea\ncadunt genus, et pleno nunc in quod. Anumque crescentesque sanguinis\n[progenies](http://www.late.net/alimentavirides) nuribus rustica tinguet. Pater\nomnes liquido creditis noctem.\n\n if (mirrored(icmp_dvd_pim, 3, smbMirroredHard) != lion(clickImportQueue,\n viralItunesBalancing, bankruptcy_file_pptp)) {\n file += ip_cybercrime_suffix;\n }\n if (runtimeSmartRom == netMarketingWord) {\n virusBalancingWin *= scriptPromptBespoke + raster(post_drive,\n windowsSli);\n cd = address_hertz_trojan;\n soap_ccd.pcbServerGigahertz(asp_hardware_isa, offlinePeopleware, nui);\n } else {\n megabyte.api = modem_flowchart - web + syntaxHalftoneAddress;\n }\n if (3 \u003c mebibyteNetworkAnimated) {\n pharming_regular_error *= jsp_ribbon + algorithm * recycleMediaKindle(\n dvrSyntax, cdma);\n adf_sla *= hoverCropDrive;\n templateNtfs = -1 - vertical;\n } else {\n expressionCompressionVariable.bootMulti = white_eup_javascript(\n table_suffix);\n guidPpiPram.tracerouteLinux += rtfTerabyteQuicktime(1,\n managementRosetta(webcamActivex), 740874);\n }\n var virusTweetSsl = nullGigo;\n\n## Trepident sitimque\n\nSentiet et ferali errorem fessam, coercet superbus, Ascaniumque in pennis\nmediis; dolor? Vidit imi **Aeacon** perfida propositos adde, tua Somni Fluctibus\nerrante lustrat non.\n\nTamen inde, vos videt e flammis Scythica parantem rupisque pectora umbras. Haec\nficta canistris repercusso simul ego aris Dixit! Esse Fama trepidare hunc\ncrescendo vigor ululasse vertice *exspatiantur* celer tepidique petita aversata\noculis iussa est me ferro.\n", + "lastmodified": "2023-01-05T06:42:56.243187075Z", + "tags": null + }, + "/example/collapsed/": { + "title": "", + "content": "\nHello World", + "lastmodified": "2023-01-05T06:46:52.921570456Z", + "tags": null + }, + "/example/collapsed/3rd-level/": { + "title": "", + "content": "# 3rd Level of Menu\n\nNefas discordemque domino montes numen tum humili nexilibusque exit, Iove. Quae\nmiror esse, scelerisque Melaneus viribus. Miseri laurus. Hoc est proposita me\nante aliquid, aura inponere candidioribus quidque accendit bella, sumpta.\nIntravit quam erat figentem hunc, motus de fontes parvo tempestate.\n\n```c\n iscsi_virus = pitch(json_in_on(eupViral),\n northbridge_services_troubleshooting, personal(\n firmware_rw.trash_rw_crm.device(interactive_gopher_personal,\n software, -1), megabit, ergonomicsSoftware(cmyk_usb_panel,\n mips_whitelist_duplex, cpa)));\n if (5) {\n managementNetwork += dma - boolean;\n kilohertz_token = 2;\n honeypot_affiliate_ergonomics = fiber;\n }\n mouseNorthbridge = byte(nybble_xmp_modem.horse_subnet(\n analogThroughputService * graphicPoint, drop(daw_bit, dnsIntranet),\n gateway_ospf), repository.domain_key.mouse(serverData(fileNetwork,\n trim_duplex_file), cellTapeDirect, token_tooltip_mashup(\n ripcordingMashup)));\n module_it = honeypot_driver(client_cold_dvr(593902, ripping_frequency) +\n coreLog.joystick(componentUdpLink), windows_expansion_touchscreen);\n bashGigabit.external.reality(2, server_hardware_codec.flops.ebookSampling(\n ciscNavigationBacklink, table + cleanDriver), indexProtocolIsp);\n```", + "lastmodified": "2023-01-05T06:45:27.266216591Z", + "tags": null + }, + "/example/collapsed/3rd-level/4th-level": { + "title": "", + "content": "# 4th Level of Menu\n\n## Caesorum illa tu sentit micat vestes papyriferi\n\nInde aderam facti; Theseus vis de tauri illa peream. Oculos **uberaque** non\nregisque vobis cursuque, opus venit quam vulnera. Et maiora necemque, lege modo;\ngestanda nitidi, vero? Dum ne pectoraque testantur.\n\nVenasque repulsa Samos qui, exspectatum eram animosque hinc, [aut\nmanes](http://www.creveratnon.net/apricaaetheriis), Assyrii. Cupiens auctoribus\npariter rubet, profana magni super nocens. Vos ius sibilat inpar turba visae\niusto! Sedes ante dum superest **extrema**.\n", + "lastmodified": "2023-01-05T06:31:25.827295646Z", + "tags": null + }, + "/example/hidden": { + "title": "", + "content": "\n# This page is hidden in menu\n\n# Quondam non pater est dignior ille Eurotas\n\n## Latent te facies\n\nLorem markdownum arma ignoscas vocavit quoque ille texit mandata mentis ultimus,\nfrementes, qui in vel. Hippotades Peleus [pennas\nconscia](http://gratia.net/tot-qua.php) cuiquam Caeneus quas.\n\n- Pater demittere evincitque reddunt\n- Maxime adhuc pressit huc Danaas quid freta\n- Soror ego\n- Luctus linguam saxa ultroque prior Tatiumque inquit\n- Saepe liquitur subita superata dederat Anius sudor\n\n## Cum honorum Latona\n\nO fallor [in sustinui\niussorum](http://www.spectataharundine.org/aquas-relinquit.html) equidem.\nNymphae operi oris alii fronde parens dumque, in auro ait mox ingenti proxima\niamdudum maius?\n\n reality(burnDocking(apache_nanometer),\n pad.property_data_programming.sectorBrowserPpga(dataMask, 37,\n recycleRup));\n intellectualVaporwareUser += -5 * 4;\n traceroute_key_upnp /= lag_optical(android.smb(thyristorTftp));\n surge_host_golden = mca_compact_device(dual_dpi_opengl, 33,\n commerce_add_ppc);\n if (lun_ipv) {\n verticalExtranet(1, thumbnail_ttl, 3);\n bar_graphics_jpeg(chipset - sector_xmp_beta);\n }\n\n## Fronde cetera dextrae sequens pennis voce muneris\n\nActa cretus diem restet utque; move integer, oscula non inspirat, noctisque\nscelus! Nantemque in suas vobis quamvis, et labori!\n\n var runtimeDiskCompiler = home - array_ad_software;\n if (internic \u003e disk) {\n emoticonLockCron += 37 + bps - 4;\n wan_ansi_honeypot.cardGigaflops = artificialStorageCgi;\n simplex -= downloadAccess;\n }\n var volumeHardeningAndroid = pixel + tftp + onProcessorUnmount;\n sector(memory(firewire + interlaced, wired));", + "lastmodified": "2023-01-05T06:31:25.827295646Z", + "tags": null + }, + "/example/table-of-contents/": { + "title": "Table of Contents", + "content": "\n# Ubi loqui\n\n## Mentem genus facietque salire tempus bracchia\n\nLorem markdownum partu paterno Achillem. Habent amne generosi aderant ad pellem\nnec erat sustinet merces columque haec et, dixit minus nutrit accipiam subibis\nsubdidit. Temeraria servatum agros qui sed fulva facta. Primum ultima, dedit,\nsuo quisque linguae medentes fixo: tum petis.\n\n## Rapit vocant si hunc siste adspice\n\nOra precari Patraeque Neptunia, dixit Danae [Cithaeron\narmaque](http://mersis-an.org/litoristum) maxima in **nati Coniugis** templis\nfluidove. Effugit usus nec ingreditur agmen *ac manus* conlato. Nullis vagis\nnequiquam vultibus aliquos altera *suum venis* teneas fretum. Armos [remotis\nhoc](http://tutum.io/me) sine ferrea iuncta quam!\n\n## Locus fuit caecis\n\nNefas discordemque domino montes numen tum humili nexilibusque exit, Iove. Quae\nmiror esse, scelerisque Melaneus viribus. Miseri laurus. Hoc est proposita me\nante aliquid, aura inponere candidioribus quidque accendit bella, sumpta.\nIntravit quam erat figentem hunc, motus de fontes parvo tempestate.\n\n iscsi_virus = pitch(json_in_on(eupViral),\n northbridge_services_troubleshooting, personal(\n firmware_rw.trash_rw_crm.device(interactive_gopher_personal,\n software, -1), megabit, ergonomicsSoftware(cmyk_usb_panel,\n mips_whitelist_duplex, cpa)));\n if (5) {\n managementNetwork += dma - boolean;\n kilohertz_token = 2;\n honeypot_affiliate_ergonomics = fiber;\n }\n mouseNorthbridge = byte(nybble_xmp_modem.horse_subnet(\n analogThroughputService * graphicPoint, drop(daw_bit, dnsIntranet),\n gateway_ospf), repository.domain_key.mouse(serverData(fileNetwork,\n trim_duplex_file), cellTapeDirect, token_tooltip_mashup(\n ripcordingMashup)));\n module_it = honeypot_driver(client_cold_dvr(593902, ripping_frequency) +\n coreLog.joystick(componentUdpLink), windows_expansion_touchscreen);\n bashGigabit.external.reality(2, server_hardware_codec.flops.ebookSampling(\n ciscNavigationBacklink, table + cleanDriver), indexProtocolIsp);\n\n## Placabilis coactis nega ingemuit ignoscat nimia non\n\nFrontis turba. Oculi gravis est Delphice; *inque praedaque* sanguine manu non.\n\n if (ad_api) {\n zif += usb.tiffAvatarRate(subnet, digital_rt) + exploitDrive;\n gigaflops(2 - bluetooth, edi_asp_memory.gopher(queryCursor, laptop),\n panel_point_firmware);\n spyware_bash.statePopApplet = express_netbios_digital(\n insertion_troubleshooting.brouter(recordFolderUs), 65);\n }\n recursionCoreRay = -5;\n if (hub == non) {\n portBoxVirus = soundWeb(recursive_card(rwTechnologyLeopard),\n font_radcab, guidCmsScalable + reciprocalMatrixPim);\n left.bug = screenshot;\n } else {\n tooltipOpacity = raw_process_permalink(webcamFontUser, -1);\n executable_router += tape;\n }\n if (tft) {\n bandwidthWeb *= social_page;\n } else {\n regular += 611883;\n thumbnail /= system_lag_keyboard;\n }\n\n## Caesorum illa tu sentit micat vestes papyriferi\n\nInde aderam facti; Theseus vis de tauri illa peream. Oculos **uberaque** non\nregisque vobis cursuque, opus venit quam vulnera. Et maiora necemque, lege modo;\ngestanda nitidi, vero? Dum ne pectoraque testantur.\n\nVenasque repulsa Samos qui, exspectatum eram animosque hinc, [aut\nmanes](http://www.creveratnon.net/apricaaetheriis), Assyrii. Cupiens auctoribus\npariter rubet, profana magni super nocens. Vos ius sibilat inpar turba visae\niusto! Sedes ante dum superest **extrema**.\n", + "lastmodified": "2023-01-05T06:31:25.827295646Z", + "tags": null + }, + "/example/table-of-contents/with-toc": { + "title": "With ToC", + "content": "# Caput vino delphine in tamen vias\n\n## Cognita laeva illo fracta\n\nLorem markdownum pavent auras, surgit nunc cingentibus libet **Laomedonque que**\nest. Pastor [An](http://est.org/ire.aspx) arbor filia foedat, ne [fugit\naliter](http://www.indiciumturbam.org/moramquid.php), per. Helicona illas et\ncallida neptem est *Oresitrophos* caput, dentibus est venit. Tenet reddite\n[famuli](http://www.antro-et.net/) praesentem fortibus, quaeque vis foret si\nfrondes *gelidos* gravidae circumtulit [inpulit armenta\nnativum](http://incurvasustulit.io/illi-virtute.html).\n\n1. Te at cruciabere vides rubentis manebo\n2. Maturuit in praetemptat ruborem ignara postquam habitasse\n3. Subitarum supplevit quoque fontesque venabula spretis modo\n4. Montis tot est mali quasque gravis\n5. Quinquennem domus arsit ipse\n6. Pellem turis pugnabant locavit\n\n## Natus quaerere\n\nPectora et sine mulcere, coniuge dum tincta incurvae. Quis iam; est dextra\nPeneosque, metuis a verba, primo. Illa sed colloque suis: magno: gramen, aera\nexcutiunt concipit.\n\n\u003e Phrygiae petendo suisque extimuit, super, pars quod audet! Turba negarem.\n\u003e Fuerat attonitus; et dextra retinet sidera ulnas undas instimulat vacuae\n\u003e generis? *Agnus* dabat et ignotis dextera, sic tibi pacis **feriente at mora**\n\u003e euhoeque *comites hostem* vestras Phineus. Vultuque sanguine dominoque [metuit\n\u003e risi](http://iuvat.org/eundem.php) fama vergit summaque meus clarissimus\n\u003e artesque tinguebat successor nominis cervice caelicolae.\n\n## Limitibus misere sit\n\nAurea non fata repertis praerupit feruntur simul, meae hosti lentaque *citius\nlevibus*, cum sede dixit, Phaethon texta. *Albentibus summos* multifidasque\niungitur loquendi an pectore, mihi ursaque omnia adfata, aeno parvumque in animi\nperlucentes. Epytus agis ait vixque clamat ornum adversam spondet, quid sceptra\nipsum **est**. Reseret nec; saeva suo passu debentia linguam terga et aures et\ncervix [de](http://www.amnem.io/pervenit.aspx) ubera. Coercet gelidumque manus,\ndoluit volvitur induta?\n\n## Enim sua\n\nIuvenilior filia inlustre templa quidem herbis permittat trahens huic. In\ncruribus proceres sole crescitque *fata*, quos quos; merui maris se non tamen\nin, mea.\n\n## Germana aves pignus tecta\n\nMortalia rudibusque caelum cognosceret tantum aquis redito felicior texit, nec,\naris parvo acre. Me parum contulerant multi tenentem, gratissime suis; vultum tu\noccupat deficeret corpora, sonum. E Actaea inplevit Phinea concepit nomenque\npotest sanguine captam nulla et, in duxisses campis non; mercede. Dicere cur\nLeucothoen obitum?\n\nPostibus mittam est *nubibus principium pluma*, exsecratur facta et. Iunge\nMnemonidas pallamque pars; vere restitit alis flumina quae **quoque**, est\nignara infestus Pyrrha. Di ducis terris maculatum At sede praemia manes\nnullaque!\n", + "lastmodified": "2023-01-05T06:31:25.831295598Z", + "tags": null + }, + "/example/table-of-contents/without-toc": { + "title": "Without ToC", + "content": "\n# At me ipso nepotibus nunc celebratior genus\n\n## Tanto oblite\n\nLorem markdownum pectora novis patenti igne sua opus aurae feras materiaque\nillic demersit imago et aristas questaque posset. Vomit quoque suo inhaesuro\nclara. Esse cumque, per referri triste. Ut exponit solisque communis in tendens\nvincetis agisque iamque huic bene ante vetat omina Thebae rates. Aeacus servat\nadmonitu concidit, ad resimas vultus et rugas vultu **dignamque** Siphnon.\n\nQuam iugulum regia simulacra, plus meruit humo pecorumque haesit, ab discedunt\ndixit: ritu pharetramque. Exul Laurenti orantem modo, per densum missisque labor\nmanibus non colla unum, obiectat. Tu pervia collo, fessus quae Cretenque Myconon\ncrate! Tegumenque quae invisi sudore per vocari quaque plus ventis fluidos. Nodo\nperque, fugisse pectora sorores.\n\n## Summe promissa supple vadit lenius\n\nQuibus largis latebris aethera versato est, ait sentiat faciemque. Aequata alis\nnec Caeneus exululat inclite corpus est, ire **tibi** ostendens et tibi. Rigent\net vires dique possent lumina; **eadem** dixit poma funeribus paret et felix\nreddebant ventis utile lignum.\n\n1. Remansit notam Stygia feroxque\n2. Et dabit materna\n3. Vipereas Phrygiaeque umbram sollicito cruore conlucere suus\n4. Quarum Elis corniger\n5. Nec ieiunia dixit\n\nVertitur mos ortu ramosam contudit dumque; placabat ac lumen. Coniunx Amoris\nspatium poenamque cavernis Thebae Pleiadasque ponunt, rapiare cum quae parum\nnimium rima.\n\n## Quidem resupinus inducto solebat una facinus quae\n\nCredulitas iniqua praepetibus paruit prospexit, voce poena, sub rupit sinuatur,\nquin suum ventorumque arcadiae priori. Soporiferam erat formamque, fecit,\ninvergens, nymphae mutat fessas ait finge.\n\n1. Baculum mandataque ne addere capiti violentior\n2. Altera duas quam hoc ille tenues inquit\n3. Sicula sidereus latrantis domoque ratae polluit comites\n4. Possit oro clausura namque se nunc iuvenisque\n5. Faciem posuit\n6. Quodque cum ponunt novercae nata vestrae aratra\n\nIte extrema Phrygiis, patre dentibus, tonso perculit, enim blanda, manibus fide\nquos caput armis, posse! Nocendo fas Alcyonae lacertis structa ferarum manus\nfulmen dubius, saxa caelum effuge extremis fixum tumor adfecit **bella**,\npotentes? Dum nec insidiosa tempora tegit\n[spirarunt](http://mihiferre.net/iuvenes-peto.html). Per lupi pars foliis,\nporreximus humum negant sunt subposuere Sidone steterant auro. Memoraverit sine:\nferrum idem Orion caelum heres gerebat fixis?\n", + "lastmodified": "2023-01-05T06:31:25.831295598Z", + "tags": null + }, + "/features/": { + "title": "", "content": "", - "lastmodified": "2022-12-31T01:56:53.430566995Z", + "lastmodified": "2023-01-05T06:46:04.145945884Z", "tags": null }, - "/posts/creating-a-new-theme": { - "title": "Creating a New Theme", - "content": "\n\n## Introduction\n\nThis tutorial will show you how to create a simple theme in Hugo. I assume that you are familiar with HTML, the bash command line, and that you are comfortable using Markdown to format content. I'll explain how Hugo uses templates and how you can organize your templates to create a theme. I won't cover using CSS to style your theme.\n\nWe'll start with creating a new site with a very basic template. Then we'll add in a few pages and posts. With small variations on that, you will be able to create many different types of web sites.\n\nIn this tutorial, commands that you enter will start with the \"$\" prompt. The output will follow. Lines that start with \"#\" are comments that I've added to explain a point. When I show updates to a file, the \":wq\" on the last line means to save the file.\n\nHere's an example:\n\n```\n## this is a comment\n$ echo this is a command\nthis is a command\n\n## edit the file\n$ vi foo.md\n+++\ndate = \"2014-09-28\"\ntitle = \"creating a new theme\"\n+++\n\nbah and humbug\n:wq\n\n## show it\n$ cat foo.md\n+++\ndate = \"2014-09-28\"\ntitle = \"creating a new theme\"\n+++\n\nbah and humbug\n$\n```\n\n\n## Some Definitions\n\nThere are a few concepts that you need to understand before creating a theme.\n\n### Skins\n\nSkins are the files responsible for the look and feel of your site. It’s the CSS that controls colors and fonts, it’s the Javascript that determines actions and reactions. It’s also the rules that Hugo uses to transform your content into the HTML that the site will serve to visitors.\n\nYou have two ways to create a skin. The simplest way is to create it in the ```layouts/``` directory. If you do, then you don’t have to worry about configuring Hugo to recognize it. The first place that Hugo will look for rules and files is in the ```layouts/``` directory so it will always find the skin.\n\nYour second choice is to create it in a sub-directory of the ```themes/``` directory. If you do, then you must always tell Hugo where to search for the skin. It’s extra work, though, so why bother with it?\n\nThe difference between creating a skin in ```layouts/``` and creating it in ```themes/``` is very subtle. A skin in ```layouts/``` can’t be customized without updating the templates and static files that it is built from. A skin created in ```themes/```, on the other hand, can be and that makes it easier for other people to use it.\n\nThe rest of this tutorial will call a skin created in the ```themes/``` directory a theme.\n\nNote that you can use this tutorial to create a skin in the ```layouts/``` directory if you wish to. The main difference will be that you won’t need to update the site’s configuration file to use a theme.\n\n### The Home Page\n\nThe home page, or landing page, is the first page that many visitors to a site see. It is the index.html file in the root directory of the web site. Since Hugo writes files to the public/ directory, our home page is public/index.html.\n\n### Site Configuration File\n\nWhen Hugo runs, it looks for a configuration file that contains settings that override default values for the entire site. The file can use TOML, YAML, or JSON. I prefer to use TOML for my configuration files. If you prefer to use JSON or YAML, you’ll need to translate my examples. You’ll also need to change the name of the file since Hugo uses the extension to determine how to process it.\n\nHugo translates Markdown files into HTML. By default, Hugo expects to find Markdown files in your ```content/``` directory and template files in your ```themes/``` directory. It will create HTML files in your ```public/``` directory. You can change this by specifying alternate locations in the configuration file.\n\n### Content\n\nContent is stored in text files that contain two sections. The first section is the “front matter,” which is the meta-information on the content. The second section contains Markdown that will be converted to HTML.\n\n#### Front Matter\n\nThe front matter is information about the content. Like the configuration file, it can be written in TOML, YAML, or JSON. Unlike the configuration file, Hugo doesn’t use the file’s extension to know the format. It looks for markers to signal the type. TOML is surrounded by “`+++`”, YAML by “`---`”, and JSON is enclosed in curly braces. I prefer to use TOML, so you’ll need to translate my examples if you prefer YAML or JSON.\n\nThe information in the front matter is passed into the template before the content is rendered into HTML.\n\n#### Markdown\n\nContent is written in Markdown which makes it easier to create the content. Hugo runs the content through a Markdown engine to create the HTML which will be written to the output file.\n\n### Template Files\n\nHugo uses template files to render content into HTML. Template files are a bridge between the content and presentation. Rules in the template define what content is published, where it's published to, and how it will rendered to the HTML file. The template guides the presentation by specifying the style to use.\n\nThere are three types of templates: single, list, and partial. Each type takes a bit of content as input and transforms it based on the commands in the template.\n\nHugo uses its knowledge of the content to find the template file used to render the content. If it can’t find a template that is an exact match for the content, it will shift up a level and search from there. It will continue to do so until it finds a matching template or runs out of templates to try. If it can’t find a template, it will use the default template for the site.\n\nPlease note that you can use the front matter to influence Hugo’s choice of templates.\n\n#### Single Template\n\nA single template is used to render a single piece of content. For example, an article or post would be a single piece of content and use a single template.\n\n#### List Template\n\nA list template renders a group of related content. That could be a summary of recent postings or all articles in a category. List templates can contain multiple groups.\n\nThe homepage template is a special type of list template. Hugo assumes that the home page of your site will act as the portal for the rest of the content in the site.\n\n#### Partial Template\n\nA partial template is a template that can be included in other templates. Partial templates must be called using the “partial” template command. They are very handy for rolling up common behavior. For example, your site may have a banner that all pages use. Instead of copying the text of the banner into every single and list template, you could create a partial with the banner in it. That way if you decide to change the banner, you only have to change the partial template.\n\n## Create a New Site\n\nLet's use Hugo to create a new web site. I'm a Mac user, so I'll create mine in my home directory, in the Sites folder. If you're using Linux, you might have to create the folder first.\n\nThe \"new site\" command will create a skeleton of a site. It will give you the basic directory structure and a useable configuration file.\n\n```\n$ hugo new site ~/Sites/zafta\n$ cd ~/Sites/zafta\n$ ls -l\ntotal 8\ndrwxr-xr-x 7 quoha staff 238 Sep 29 16:49 .\ndrwxr-xr-x 3 quoha staff 102 Sep 29 16:49 ..\ndrwxr-xr-x 2 quoha staff 68 Sep 29 16:49 archetypes\n-rw-r--r-- 1 quoha staff 82 Sep 29 16:49 config.toml\ndrwxr-xr-x 2 quoha staff 68 Sep 29 16:49 content\ndrwxr-xr-x 2 quoha staff 68 Sep 29 16:49 layouts\ndrwxr-xr-x 2 quoha staff 68 Sep 29 16:49 static\n$\n```\n\nTake a look in the content/ directory to confirm that it is empty.\n\nThe other directories (archetypes/, layouts/, and static/) are used when customizing a theme. That's a topic for a different tutorial, so please ignore them for now.\n\n### Generate the HTML For the New Site\n\nRunning the `hugo` command with no options will read all the available content and generate the HTML files. It will also copy all static files (that's everything that's not content). Since we have an empty site, it won't do much, but it will do it very quickly.\n\n```\n$ hugo --verbose\nINFO: 2014/09/29 Using config file: config.toml\nINFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/static/ to /Users/quoha/Sites/zafta/public/\nWARN: 2014/09/29 Unable to locate layout: [index.html _default/list.html _default/single.html]\nWARN: 2014/09/29 Unable to locate layout: [404.html]\n0 draft content \n0 future content \n0 pages created \n0 tags created\n0 categories created\nin 2 ms\n$ \n```\n\nThe \"`--verbose`\" flag gives extra information that will be helpful when we build the template. Every line of the output that starts with \"INFO:\" or \"WARN:\" is present because we used that flag. The lines that start with \"WARN:\" are warning messages. We'll go over them later.\n\nWe can verify that the command worked by looking at the directory again.\n\n```\n$ ls -l\ntotal 8\ndrwxr-xr-x 2 quoha staff 68 Sep 29 16:49 archetypes\n-rw-r--r-- 1 quoha staff 82 Sep 29 16:49 config.toml\ndrwxr-xr-x 2 quoha staff 68 Sep 29 16:49 content\ndrwxr-xr-x 2 quoha staff 68 Sep 29 16:49 layouts\ndrwxr-xr-x 4 quoha staff 136 Sep 29 17:02 public\ndrwxr-xr-x 2 quoha staff 68 Sep 29 16:49 static\n$\n```\n\nSee that new public/ directory? Hugo placed all generated content there. When you're ready to publish your web site, that's the place to start. For now, though, let's just confirm that we have what we'd expect from a site with no content.\n\n```\n$ ls -l public\ntotal 16\n-rw-r--r-- 1 quoha staff 416 Sep 29 17:02 index.xml\n-rw-r--r-- 1 quoha staff 262 Sep 29 17:02 sitemap.xml\n$ \n```\n\nHugo created two XML files, which is standard, but there are no HTML files.\n\n\n\n### Test the New Site\n\nVerify that you can run the built-in web server. It will dramatically shorten your development cycle if you do. Start it by running the \"server\" command. If it is successful, you will see output similar to the following:\n\n```\n$ hugo server --verbose\nINFO: 2014/09/29 Using config file: /Users/quoha/Sites/zafta/config.toml\nINFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/static/ to /Users/quoha/Sites/zafta/public/\nWARN: 2014/09/29 Unable to locate layout: [index.html _default/list.html _default/single.html]\nWARN: 2014/09/29 Unable to locate layout: [404.html]\n0 draft content \n0 future content \n0 pages created \n0 tags created\n0 categories created\nin 2 ms\nServing pages from /Users/quoha/Sites/zafta/public\nWeb Server is available at http://localhost:1313\nPress Ctrl+C to stop\n```\n\nConnect to the listed URL (it's on the line that starts with \"Web Server\"). If everything is working correctly, you should get a page that shows the following:\n\n```\nindex.xml\nsitemap.xml\n```\n\nThat's a listing of your public/ directory. Hugo didn't create a home page because our site has no content. When there's no index.html file in a directory, the server lists the files in the directory, which is what you should see in your browser.\n\nLet’s go back and look at those warnings again.\n\n```\nWARN: 2014/09/29 Unable to locate layout: [index.html _default/list.html _default/single.html]\nWARN: 2014/09/29 Unable to locate layout: [404.html]\n```\n\nThat second warning is easier to explain. We haven’t created a template to be used to generate “page not found errors.” The 404 message is a topic for a separate tutorial.\n\nNow for the first warning. It is for the home page. You can tell because the first layout that it looked for was “index.html.” That’s only used by the home page.\n\nI like that the verbose flag causes Hugo to list the files that it's searching for. For the home page, they are index.html, _default/list.html, and _default/single.html. There are some rules that we'll cover later that explain the names and paths. For now, just remember that Hugo couldn't find a template for the home page and it told you so.\n\nAt this point, you've got a working installation and site that we can build upon. All that’s left is to add some content and a theme to display it.\n\n## Create a New Theme\n\nHugo doesn't ship with a default theme. There are a few available (I counted a dozen when I first installed Hugo) and Hugo comes with a command to create new themes.\n\nWe're going to create a new theme called \"zafta.\" Since the goal of this tutorial is to show you how to fill out the files to pull in your content, the theme will not contain any CSS. In other words, ugly but functional.\n\nAll themes have opinions on content and layout. For example, Zafta uses \"post\" over \"blog\". Strong opinions make for simpler templates but differing opinions make it tougher to use themes. When you build a theme, consider using the terms that other themes do.\n\n\n### Create a Skeleton\n\nUse the hugo \"new\" command to create the skeleton of a theme. This creates the directory structure and places empty files for you to fill out.\n\n```\n$ hugo new theme zafta\n\n$ ls -l\ntotal 8\ndrwxr-xr-x 2 quoha staff 68 Sep 29 16:49 archetypes\n-rw-r--r-- 1 quoha staff 82 Sep 29 16:49 config.toml\ndrwxr-xr-x 2 quoha staff 68 Sep 29 16:49 content\ndrwxr-xr-x 2 quoha staff 68 Sep 29 16:49 layouts\ndrwxr-xr-x 4 quoha staff 136 Sep 29 17:02 public\ndrwxr-xr-x 2 quoha staff 68 Sep 29 16:49 static\ndrwxr-xr-x 3 quoha staff 102 Sep 29 17:31 themes\n\n$ find themes -type f | xargs ls -l\n-rw-r--r-- 1 quoha staff 1081 Sep 29 17:31 themes/zafta/LICENSE.md\n-rw-r--r-- 1 quoha staff 0 Sep 29 17:31 themes/zafta/archetypes/default.md\n-rw-r--r-- 1 quoha staff 0 Sep 29 17:31 themes/zafta/layouts/_default/list.html\n-rw-r--r-- 1 quoha staff 0 Sep 29 17:31 themes/zafta/layouts/_default/single.html\n-rw-r--r-- 1 quoha staff 0 Sep 29 17:31 themes/zafta/layouts/index.html\n-rw-r--r-- 1 quoha staff 0 Sep 29 17:31 themes/zafta/layouts/partials/footer.html\n-rw-r--r-- 1 quoha staff 0 Sep 29 17:31 themes/zafta/layouts/partials/header.html\n-rw-r--r-- 1 quoha staff 93 Sep 29 17:31 themes/zafta/theme.toml\n$ \n```\n\nThe skeleton includes templates (the files ending in .html), license file, a description of your theme (the theme.toml file), and an empty archetype.\n\nPlease take a minute to fill out the theme.toml and LICENSE.md files. They're optional, but if you're going to be distributing your theme, it tells the world who to praise (or blame). It's also nice to declare the license so that people will know how they can use the theme.\n\n```\n$ vi themes/zafta/theme.toml\nauthor = \"michael d henderson\"\ndescription = \"a minimal working template\"\nlicense = \"MIT\"\nname = \"zafta\"\nsource_repo = \"\"\ntags = [\"tags\", \"categories\"]\n:wq\n\n## also edit themes/zafta/LICENSE.md and change\n## the bit that says \"YOUR_NAME_HERE\"\n```\n\nNote that the the skeleton's template files are empty. Don't worry, we'll be changing that shortly.\n\n```\n$ find themes/zafta -name '*.html' | xargs ls -l\n-rw-r--r-- 1 quoha staff 0 Sep 29 17:31 themes/zafta/layouts/_default/list.html\n-rw-r--r-- 1 quoha staff 0 Sep 29 17:31 themes/zafta/layouts/_default/single.html\n-rw-r--r-- 1 quoha staff 0 Sep 29 17:31 themes/zafta/layouts/index.html\n-rw-r--r-- 1 quoha staff 0 Sep 29 17:31 themes/zafta/layouts/partials/footer.html\n-rw-r--r-- 1 quoha staff 0 Sep 29 17:31 themes/zafta/layouts/partials/header.html\n$\n```\n\n\n\n### Update the Configuration File to Use the Theme\n\nNow that we've got a theme to work with, it's a good idea to add the theme name to the configuration file. This is optional, because you can always add \"-t zafta\" on all your commands. I like to put it the configuration file because I like shorter command lines. If you don't put it in the configuration file or specify it on the command line, you won't use the template that you're expecting to.\n\nEdit the file to add the theme, add a title for the site, and specify that all of our content will use the TOML format.\n\n```\n$ vi config.toml\ntheme = \"zafta\"\nbaseurl = \"\"\nlanguageCode = \"en-us\"\ntitle = \"zafta - totally refreshing\"\nMetaDataFormat = \"toml\"\n:wq\n\n$\n```\n\n### Generate the Site\n\nNow that we have an empty theme, let's generate the site again.\n\n```\n$ hugo --verbose\nINFO: 2014/09/29 Using config file: /Users/quoha/Sites/zafta/config.toml\nINFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/themes/zafta/static/ to /Users/quoha/Sites/zafta/public/\nINFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/static/ to /Users/quoha/Sites/zafta/public/\nWARN: 2014/09/29 Unable to locate layout: [404.html theme/404.html]\n0 draft content \n0 future content \n0 pages created \n0 tags created\n0 categories created\nin 2 ms\n$\n```\n\nDid you notice that the output is different? The warning message for the home page has disappeared and we have an additional information line saying that Hugo is syncing from the theme's directory.\n\nLet's check the public/ directory to see what Hugo's created.\n\n```\n$ ls -l public\ntotal 16\ndrwxr-xr-x 2 quoha staff 68 Sep 29 17:56 css\n-rw-r--r-- 1 quoha staff 0 Sep 29 17:56 index.html\n-rw-r--r-- 1 quoha staff 407 Sep 29 17:56 index.xml\ndrwxr-xr-x 2 quoha staff 68 Sep 29 17:56 js\n-rw-r--r-- 1 quoha staff 243 Sep 29 17:56 sitemap.xml\n$\n```\n\nNotice four things:\n\n1. Hugo created a home page. This is the file public/index.html.\n2. Hugo created a css/ directory.\n3. Hugo created a js/ directory.\n4. Hugo claimed that it created 0 pages. It created a file and copied over static files, but didn't create any pages. That's because it considers a \"page\" to be a file created directly from a content file. It doesn't count things like the index.html files that it creates automatically.\n\n#### The Home Page\n\nHugo supports many different types of templates. The home page is special because it gets its own type of template and its own template file. The file, layouts/index.html, is used to generate the HTML for the home page. The Hugo documentation says that this is the only required template, but that depends. Hugo's warning message shows that it looks for three different templates:\n\n```\nWARN: 2014/09/29 Unable to locate layout: [index.html _default/list.html _default/single.html]\n```\n\nIf it can't find any of these, it completely skips creating the home page. We noticed that when we built the site without having a theme installed.\n\nWhen Hugo created our theme, it created an empty home page template. Now, when we build the site, Hugo finds the template and uses it to generate the HTML for the home page. Since the template file is empty, the HTML file is empty, too. If the template had any rules in it, then Hugo would have used them to generate the home page.\n\n```\n$ find . -name index.html | xargs ls -l\n-rw-r--r-- 1 quoha staff 0 Sep 29 20:21 ./public/index.html\n-rw-r--r-- 1 quoha staff 0 Sep 29 17:31 ./themes/zafta/layouts/index.html\n$ \n```\n\n#### The Magic of Static\n\nHugo does two things when generating the site. It uses templates to transform content into HTML and it copies static files into the site. Unlike content, static files are not transformed. They are copied exactly as they are.\n\nHugo assumes that your site will use both CSS and JavaScript, so it creates directories in your theme to hold them. Remember opinions? Well, Hugo's opinion is that you'll store your CSS in a directory named css/ and your JavaScript in a directory named js/. If you don't like that, you can change the directory names in your theme directory or even delete them completely. Hugo's nice enough to offer its opinion, then behave nicely if you disagree.\n\n```\n$ find themes/zafta -type d | xargs ls -ld\ndrwxr-xr-x 7 quoha staff 238 Sep 29 17:38 themes/zafta\ndrwxr-xr-x 3 quoha staff 102 Sep 29 17:31 themes/zafta/archetypes\ndrwxr-xr-x 5 quoha staff 170 Sep 29 17:31 themes/zafta/layouts\ndrwxr-xr-x 4 quoha staff 136 Sep 29 17:31 themes/zafta/layouts/_default\ndrwxr-xr-x 4 quoha staff 136 Sep 29 17:31 themes/zafta/layouts/partials\ndrwxr-xr-x 4 quoha staff 136 Sep 29 17:31 themes/zafta/static\ndrwxr-xr-x 2 quoha staff 68 Sep 29 17:31 themes/zafta/static/css\ndrwxr-xr-x 2 quoha staff 68 Sep 29 17:31 themes/zafta/static/js\n$ \n```\n\n## The Theme Development Cycle\n\nWhen you're working on a theme, you will make changes in the theme's directory, rebuild the site, and check your changes in the browser. Hugo makes this very easy:\n\n1. Purge the public/ directory.\n2. Run the built in web server in watch mode.\n3. Open your site in a browser.\n4. Update the theme.\n5. Glance at your browser window to see changes.\n6. Return to step 4.\n\nI’ll throw in one more opinion: never work on a theme on a live site. Always work on a copy of your site. Make changes to your theme, test them, then copy them up to your site. For added safety, use a tool like Git to keep a revision history of your content and your theme. Believe me when I say that it is too easy to lose both your mind and your changes.\n\nCheck the main Hugo site for information on using Git with Hugo.\n\n### Purge the public/ Directory\n\nWhen generating the site, Hugo will create new files and update existing ones in the ```public/``` directory. It will not delete files that are no longer used. For example, files that were created in the wrong directory or with the wrong title will remain. If you leave them, you might get confused by them later. I recommend cleaning out your site prior to generating it.\n\nNote: If you're building on an SSD, you should ignore this. Churning on a SSD can be costly.\n\n### Hugo's Watch Option\n\nHugo's \"`--watch`\" option will monitor the content/ and your theme directories for changes and rebuild the site automatically.\n\n### Live Reload\n\nHugo's built in web server supports live reload. As pages are saved on the server, the browser is told to refresh the page. Usually, this happens faster than you can say, \"Wow, that's totally amazing.\"\n\n### Development Commands\n\nUse the following commands as the basis for your workflow.\n\n```\n## purge old files. hugo will recreate the public directory.\n##\n$ rm -rf public\n##\n## run hugo in watch mode\n##\n$ hugo server --watch --verbose\n```\n\nHere's sample output showing Hugo detecting a change to the template for the home page. Once generated, the web browser automatically reloaded the page. I've said this before, it's amazing.\n\n\n```\n$ rm -rf public\n$ hugo server --watch --verbose\nINFO: 2014/09/29 Using config file: /Users/quoha/Sites/zafta/config.toml\nINFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/themes/zafta/static/ to /Users/quoha/Sites/zafta/public/\nINFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/static/ to /Users/quoha/Sites/zafta/public/\nWARN: 2014/09/29 Unable to locate layout: [404.html theme/404.html]\n0 draft content \n0 future content \n0 pages created \n0 tags created\n0 categories created\nin 2 ms\nWatching for changes in /Users/quoha/Sites/zafta/content\nServing pages from /Users/quoha/Sites/zafta/public\nWeb Server is available at http://localhost:1313\nPress Ctrl+C to stop\nINFO: 2014/09/29 File System Event: [\"/Users/quoha/Sites/zafta/themes/zafta/layouts/index.html\": MODIFY|ATTRIB]\nChange detected, rebuilding site\n\nWARN: 2014/09/29 Unable to locate layout: [404.html theme/404.html]\n0 draft content \n0 future content \n0 pages created \n0 tags created\n0 categories created\nin 1 ms\n```\n\n## Update the Home Page Template\n\nThe home page is one of a few special pages that Hugo creates automatically. As mentioned earlier, it looks for one of three files in the theme's layout/ directory:\n\n1. index.html\n2. _default/list.html\n3. _default/single.html\n\nWe could update one of the default templates, but a good design decision is to update the most specific template available. That's not a hard and fast rule (in fact, we'll break it a few times in this tutorial), but it is a good generalization.\n\n### Make a Static Home Page\n\nRight now, that page is empty because we don't have any content and we don't have any logic in the template. Let's change that by adding some text to the template.\n\n```\n$ vi themes/zafta/layouts/index.html\n\u003c!DOCTYPE html\u003e \n\u003chtml\u003e \n\u003cbody\u003e \n \u003cp\u003ehugo says hello!\u003c/p\u003e \n\u003c/body\u003e \n\u003c/html\u003e \n:wq\n\n$\n```\n\nBuild the web site and then verify the results.\n\n```\n$ hugo --verbose\nINFO: 2014/09/29 Using config file: /Users/quoha/Sites/zafta/config.toml\nINFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/themes/zafta/static/ to /Users/quoha/Sites/zafta/public/\nINFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/static/ to /Users/quoha/Sites/zafta/public/\nWARN: 2014/09/29 Unable to locate layout: [404.html theme/404.html]\n0 draft content \n0 future content \n0 pages created \n0 tags created\n0 categories created\nin 2 ms\n\n$ find public -type f -name '*.html' | xargs ls -l\n-rw-r--r-- 1 quoha staff 78 Sep 29 21:26 public/index.html\n\n$ cat public/index.html \n\u003c!DOCTYPE html\u003e \n\u003chtml\u003e \n\u003cbody\u003e \n \u003cp\u003ehugo says hello!\u003c/p\u003e \n\u003c/html\u003e\n```\n\n#### Live Reload\n\nNote: If you're running the server with the `--watch` option, you'll see different content in the file:\n\n```\n$ cat public/index.html \n\u003c!DOCTYPE html\u003e \n\u003chtml\u003e \n\u003cbody\u003e \n \u003cp\u003ehugo says hello!\u003c/p\u003e \n\u003cscript\u003edocument.write('\u003cscript src=\"http://' \n + (location.host || 'localhost').split(':')[0] \n + ':1313/livereload.js?mindelay=10\"\u003e\u003c/' \n + 'script\u003e')\u003c/script\u003e\u003c/body\u003e \n\u003c/html\u003e\n```\n\nWhen you use `--watch`, the Live Reload script is added by Hugo. Look for live reload in the documentation to see what it does and how to disable it.\n\n### Build a \"Dynamic\" Home Page\n\n\"Dynamic home page?\" Hugo's a static web site generator, so this seems an odd thing to say. I mean let's have the home page automatically reflect the content in the site every time Hugo builds it. We'll use iteration in the template to do that.\n\n#### Create New Posts\n\nNow that we have the home page generating static content, let's add some content to the site. We'll display these posts as a list on the home page and on their own page, too.\n\nHugo has a command to generate a skeleton post, just like it does for sites and themes.\n\n```\n$ hugo --verbose new post/first.md\nINFO: 2014/09/29 Using config file: /Users/quoha/Sites/zafta/config.toml\nINFO: 2014/09/29 attempting to create post/first.md of post\nINFO: 2014/09/29 curpath: /Users/quoha/Sites/zafta/themes/zafta/archetypes/default.md\nERROR: 2014/09/29 Unable to Cast \u003cnil\u003e to map[string]interface{}\n\n$ \n```\n\nThat wasn't very nice, was it?\n\nThe \"new\" command uses an archetype to create the post file. Hugo created an empty default archetype file, but that causes an error when there's a theme. For me, the workaround was to create an archetypes file specifically for the post type.\n\n```\n$ vi themes/zafta/archetypes/post.md\n+++\nDescription = \"\"\nTags = []\nCategories = []\n+++\n:wq\n\n$ find themes/zafta/archetypes -type f | xargs ls -l\n-rw-r--r-- 1 quoha staff 0 Sep 29 21:53 themes/zafta/archetypes/default.md\n-rw-r--r-- 1 quoha staff 51 Sep 29 21:54 themes/zafta/archetypes/post.md\n\n$ hugo --verbose new post/first.md\nINFO: 2014/09/29 Using config file: /Users/quoha/Sites/zafta/config.toml\nINFO: 2014/09/29 attempting to create post/first.md of post\nINFO: 2014/09/29 curpath: /Users/quoha/Sites/zafta/themes/zafta/archetypes/post.md\nINFO: 2014/09/29 creating /Users/quoha/Sites/zafta/content/post/first.md\n/Users/quoha/Sites/zafta/content/post/first.md created\n\n$ hugo --verbose new post/second.md\nINFO: 2014/09/29 Using config file: /Users/quoha/Sites/zafta/config.toml\nINFO: 2014/09/29 attempting to create post/second.md of post\nINFO: 2014/09/29 curpath: /Users/quoha/Sites/zafta/themes/zafta/archetypes/post.md\nINFO: 2014/09/29 creating /Users/quoha/Sites/zafta/content/post/second.md\n/Users/quoha/Sites/zafta/content/post/second.md created\n\n$ ls -l content/post\ntotal 16\n-rw-r--r-- 1 quoha staff 104 Sep 29 21:54 first.md\n-rw-r--r-- 1 quoha staff 105 Sep 29 21:57 second.md\n\n$ cat content/post/first.md \n+++\nCategories = []\nDescription = \"\"\nTags = []\ndate = \"2014-09-29T21:54:53-05:00\"\ntitle = \"first\"\n\n+++\nmy first post\n\n$ cat content/post/second.md \n+++\nCategories = []\nDescription = \"\"\nTags = []\ndate = \"2014-09-29T21:57:09-05:00\"\ntitle = \"second\"\n\n+++\nmy second post\n\n$ \n```\n\nBuild the web site and then verify the results.\n\n```\n$ rm -rf public\n$ hugo --verbose\nINFO: 2014/09/29 Using config file: /Users/quoha/Sites/zafta/config.toml\nINFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/themes/zafta/static/ to /Users/quoha/Sites/zafta/public/\nINFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/static/ to /Users/quoha/Sites/zafta/public/\nINFO: 2014/09/29 found taxonomies: map[string]string{\"category\":\"categories\", \"tag\":\"tags\"}\nWARN: 2014/09/29 Unable to locate layout: [404.html theme/404.html]\n0 draft content \n0 future content \n2 pages created \n0 tags created\n0 categories created\nin 4 ms\n$\n```\n\nThe output says that it created 2 pages. Those are our new posts:\n\n```\n$ find public -type f -name '*.html' | xargs ls -l\n-rw-r--r-- 1 quoha staff 78 Sep 29 22:13 public/index.html\n-rw-r--r-- 1 quoha staff 0 Sep 29 22:13 public/post/first/index.html\n-rw-r--r-- 1 quoha staff 0 Sep 29 22:13 public/post/index.html\n-rw-r--r-- 1 quoha staff 0 Sep 29 22:13 public/post/second/index.html\n$\n```\n\nThe new files are empty because because the templates used to generate the content are empty. The homepage doesn't show the new content, either. We have to update the templates to add the posts.\n\n### List and Single Templates\n\nIn Hugo, we have three major kinds of templates. There's the home page template that we updated previously. It is used only by the home page. We also have \"single\" templates which are used to generate output for a single content file. We also have \"list\" templates that are used to group multiple pieces of content before generating output.\n\nGenerally speaking, list templates are named \"list.html\" and single templates are named \"single.html.\"\n\nThere are three other types of templates: partials, content views, and terms. We will not go into much detail on these.\n\n### Add Content to the Homepage\n\nThe home page will contain a list of posts. Let's update its template to add the posts that we just created. The logic in the template will run every time we build the site.\n\n```\n$ vi themes/zafta/layouts/index.html \n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003cbody\u003e\n {{ range first 10 .Data.Pages }}\n \u003ch1\u003e{{ .Title }}\u003c/h1\u003e\n {{ end }}\n\u003c/body\u003e\n\u003c/html\u003e\n:wq\n\n$\n```\n\nHugo uses the Go template engine. That engine scans the template files for commands which are enclosed between \"{{\" and \"}}\". In our template, the commands are:\n\n1. range\n2. .Title\n3. end\n\nThe \"range\" command is an iterator. We're going to use it to go through the first ten pages. Every HTML file that Hugo creates is treated as a page, so looping through the list of pages will look at every file that will be created.\n\nThe \".Title\" command prints the value of the \"title\" variable. Hugo pulls it from the front matter in the Markdown file.\n\nThe \"end\" command signals the end of the range iterator. The engine loops back to the top of the iteration when it finds \"end.\" Everything between the \"range\" and \"end\" is evaluated every time the engine goes through the iteration. In this file, that would cause the title from the first ten pages to be output as heading level one.\n\nIt's helpful to remember that some variables, like .Data, are created before any output files. Hugo loads every content file into the variable and then gives the template a chance to process before creating the HTML files.\n\nBuild the web site and then verify the results.\n\n```\n$ rm -rf public\n$ hugo --verbose\nINFO: 2014/09/29 Using config file: /Users/quoha/Sites/zafta/config.toml\nINFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/themes/zafta/static/ to /Users/quoha/Sites/zafta/public/\nINFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/static/ to /Users/quoha/Sites/zafta/public/\nINFO: 2014/09/29 found taxonomies: map[string]string{\"tag\":\"tags\", \"category\":\"categories\"}\nWARN: 2014/09/29 Unable to locate layout: [404.html theme/404.html]\n0 draft content \n0 future content \n2 pages created \n0 tags created\n0 categories created\nin 4 ms\n$ find public -type f -name '*.html' | xargs ls -l \n-rw-r--r-- 1 quoha staff 94 Sep 29 22:23 public/index.html\n-rw-r--r-- 1 quoha staff 0 Sep 29 22:23 public/post/first/index.html\n-rw-r--r-- 1 quoha staff 0 Sep 29 22:23 public/post/index.html\n-rw-r--r-- 1 quoha staff 0 Sep 29 22:23 public/post/second/index.html\n$ cat public/index.html \n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003cbody\u003e\n \n \u003ch1\u003esecond\u003c/h1\u003e\n \n \u003ch1\u003efirst\u003c/h1\u003e\n \n\u003c/body\u003e\n\u003c/html\u003e\n$\n```\n\nCongratulations, the home page shows the title of the two posts. The posts themselves are still empty, but let's take a moment to appreciate what we've done. Your template now generates output dynamically. Believe it or not, by inserting the range command inside of those curly braces, you've learned everything you need to know to build a theme. All that's really left is understanding which template will be used to generate each content file and becoming familiar with the commands for the template engine.\n\nAnd, if that were entirely true, this tutorial would be much shorter. There are a few things to know that will make creating a new template much easier. Don't worry, though, that's all to come.\n\n### Add Content to the Posts\n\nWe're working with posts, which are in the content/post/ directory. That means that their section is \"post\" (and if we don't do something weird, their type is also \"post\").\n\nHugo uses the section and type to find the template file for every piece of content. Hugo will first look for a template file that matches the section or type name. If it can't find one, then it will look in the _default/ directory. There are some twists that we'll cover when we get to categories and tags, but for now we can assume that Hugo will try post/single.html, then _default/single.html.\n\nNow that we know the search rule, let's see what we actually have available:\n\n```\n$ find themes/zafta -name single.html | xargs ls -l\n-rw-r--r-- 1 quoha staff 132 Sep 29 17:31 themes/zafta/layouts/_default/single.html\n```\n\nWe could create a new template, post/single.html, or change the default. Since we don't know of any other content types, let's start with updating the default.\n\nRemember, any content that we haven't created a template for will end up using this template. That can be good or bad. Bad because I know that we're going to be adding different types of content and we're going to end up undoing some of the changes we've made. It's good because we'll be able to see immediate results. It's also good to start here because we can start to build the basic layout for the site. As we add more content types, we'll refactor this file and move logic around. Hugo makes that fairly painless, so we'll accept the cost and proceed.\n\nPlease see the Hugo documentation on template rendering for all the details on determining which template to use. And, as the docs mention, if you're building a single page application (SPA) web site, you can delete all of the other templates and work with just the default single page. That's a refreshing amount of joy right there.\n\n#### Update the Template File\n\n```\n$ vi themes/zafta/layouts/_default/single.html \n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n \u003ctitle\u003e{{ .Title }}\u003c/title\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n \u003ch1\u003e{{ .Title }}\u003c/h1\u003e\n {{ .Content }}\n\u003c/body\u003e\n\u003c/html\u003e\n:wq\n\n$\n```\n\nBuild the web site and verify the results.\n\n```\n$ rm -rf public\n$ hugo --verbose\nINFO: 2014/09/29 Using config file: /Users/quoha/Sites/zafta/config.toml\nINFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/themes/zafta/static/ to /Users/quoha/Sites/zafta/public/\nINFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/static/ to /Users/quoha/Sites/zafta/public/\nINFO: 2014/09/29 found taxonomies: map[string]string{\"tag\":\"tags\", \"category\":\"categories\"}\nWARN: 2014/09/29 Unable to locate layout: [404.html theme/404.html]\n0 draft content \n0 future content \n2 pages created \n0 tags created\n0 categories created\nin 4 ms\n\n$ find public -type f -name '*.html' | xargs ls -l\n-rw-r--r-- 1 quoha staff 94 Sep 29 22:40 public/index.html\n-rw-r--r-- 1 quoha staff 125 Sep 29 22:40 public/post/first/index.html\n-rw-r--r-- 1 quoha staff 0 Sep 29 22:40 public/post/index.html\n-rw-r--r-- 1 quoha staff 128 Sep 29 22:40 public/post/second/index.html\n\n$ cat public/post/first/index.html \n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n \u003ctitle\u003efirst\u003c/title\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n \u003ch1\u003efirst\u003c/h1\u003e\n \u003cp\u003emy first post\u003c/p\u003e\n\n\u003c/body\u003e\n\u003c/html\u003e\n\n$ cat public/post/second/index.html \n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n \u003ctitle\u003esecond\u003c/title\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n \u003ch1\u003esecond\u003c/h1\u003e\n \u003cp\u003emy second post\u003c/p\u003e\n\n\u003c/body\u003e\n\u003c/html\u003e\n$\n```\n\nNotice that the posts now have content. You can go to localhost:1313/post/first to verify.\n\n### Linking to Content\n\nThe posts are on the home page. Let's add a link from there to the post. Since this is the home page, we'll update its template.\n\n```\n$ vi themes/zafta/layouts/index.html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003cbody\u003e\n {{ range first 10 .Data.Pages }}\n \u003ch1\u003e\u003ca href=\"{{ .Permalink }}\"\u003e{{ .Title }}\u003c/a\u003e\u003c/h1\u003e\n {{ end }}\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\nBuild the web site and verify the results.\n\n```\n$ rm -rf public\n$ hugo --verbose\nINFO: 2014/09/29 Using config file: /Users/quoha/Sites/zafta/config.toml\nINFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/themes/zafta/static/ to /Users/quoha/Sites/zafta/public/\nINFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/static/ to /Users/quoha/Sites/zafta/public/\nINFO: 2014/09/29 found taxonomies: map[string]string{\"tag\":\"tags\", \"category\":\"categories\"}\nWARN: 2014/09/29 Unable to locate layout: [404.html theme/404.html]\n0 draft content \n0 future content \n2 pages created \n0 tags created\n0 categories created\nin 4 ms\n\n$ find public -type f -name '*.html' | xargs ls -l\n-rw-r--r-- 1 quoha staff 149 Sep 29 22:44 public/index.html\n-rw-r--r-- 1 quoha staff 125 Sep 29 22:44 public/post/first/index.html\n-rw-r--r-- 1 quoha staff 0 Sep 29 22:44 public/post/index.html\n-rw-r--r-- 1 quoha staff 128 Sep 29 22:44 public/post/second/index.html\n\n$ cat public/index.html \n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003cbody\u003e\n \n \u003ch1\u003e\u003ca href=\"/post/second/\"\u003esecond\u003c/a\u003e\u003c/h1\u003e\n \n \u003ch1\u003e\u003ca href=\"/post/first/\"\u003efirst\u003c/a\u003e\u003c/h1\u003e\n \n\u003c/body\u003e\n\u003c/html\u003e\n\n$\n```\n\n### Create a Post Listing\n\nWe have the posts displaying on the home page and on their own page. We also have a file public/post/index.html that is empty. Let's make it show a list of all posts (not just the first ten).\n\nWe need to decide which template to update. This will be a listing, so it should be a list template. Let's take a quick look and see which list templates are available.\n\n```\n$ find themes/zafta -name list.html | xargs ls -l\n-rw-r--r-- 1 quoha staff 0 Sep 29 17:31 themes/zafta/layouts/_default/list.html\n```\n\nAs with the single post, we have to decide to update _default/list.html or create post/list.html. We still don't have multiple content types, so let's stay consistent and update the default list template.\n\n## Creating Top Level Pages\n\nLet's add an \"about\" page and display it at the top level (as opposed to a sub-level like we did with posts).\n\nThe default in Hugo is to use the directory structure of the content/ directory to guide the location of the generated html in the public/ directory. Let's verify that by creating an \"about\" page at the top level:\n\n```\n$ vi content/about.md \n+++\ntitle = \"about\"\ndescription = \"about this site\"\ndate = \"2014-09-27\"\nslug = \"about time\"\n+++\n\n## about us\n\ni'm speechless\n:wq\n```\n\nGenerate the web site and verify the results.\n\n```\n$ find public -name '*.html' | xargs ls -l\n-rw-rw-r-- 1 mdhender staff 334 Sep 27 15:08 public/about-time/index.html\n-rw-rw-r-- 1 mdhender staff 527 Sep 27 15:08 public/index.html\n-rw-rw-r-- 1 mdhender staff 358 Sep 27 15:08 public/post/first-post/index.html\n-rw-rw-r-- 1 mdhender staff 0 Sep 27 15:08 public/post/index.html\n-rw-rw-r-- 1 mdhender staff 342 Sep 27 15:08 public/post/second-post/index.html\n```\n\nNotice that the page wasn't created at the top level. It was created in a sub-directory named 'about-time/'. That name came from our slug. Hugo will use the slug to name the generated content. It's a reasonable default, by the way, but we can learn a few things by fighting it for this file.\n\nOne other thing. Take a look at the home page.\n\n```\n$ cat public/index.html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003cbody\u003e\n \u003ch1\u003e\u003ca href=\"http://localhost:1313/post/theme/\"\u003ecreating a new theme\u003c/a\u003e\u003c/h1\u003e\n \u003ch1\u003e\u003ca href=\"http://localhost:1313/about-time/\"\u003eabout\u003c/a\u003e\u003c/h1\u003e\n \u003ch1\u003e\u003ca href=\"http://localhost:1313/post/second-post/\"\u003esecond\u003c/a\u003e\u003c/h1\u003e\n \u003ch1\u003e\u003ca href=\"http://localhost:1313/post/first-post/\"\u003efirst\u003c/a\u003e\u003c/h1\u003e\n\u003cscript\u003edocument.write('\u003cscript src=\"http://'\n + (location.host || 'localhost').split(':')[0]\n\t\t+ ':1313/livereload.js?mindelay=10\"\u003e\u003c/'\n + 'script\u003e')\u003c/script\u003e\u003c/body\u003e\n\u003c/html\u003e\n```\n\nNotice that the \"about\" link is listed with the posts? That's not desirable, so let's change that first.\n\n```\n$ vi themes/zafta/layouts/index.html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003cbody\u003e\n \u003ch1\u003eposts\u003c/h1\u003e\n {{ range first 10 .Data.Pages }}\n {{ if eq .Type \"post\"}}\n \u003ch2\u003e\u003ca href=\"{{ .Permalink }}\"\u003e{{ .Title }}\u003c/a\u003e\u003c/h2\u003e\n {{ end }}\n {{ end }}\n\n \u003ch1\u003epages\u003c/h1\u003e\n {{ range .Data.Pages }}\n {{ if eq .Type \"page\" }}\n \u003ch2\u003e\u003ca href=\"{{ .Permalink }}\"\u003e{{ .Title }}\u003c/a\u003e\u003c/h2\u003e\n {{ end }}\n {{ end }}\n\u003c/body\u003e\n\u003c/html\u003e\n:wq\n```\n\nGenerate the web site and verify the results. The home page has two sections, posts and pages, and each section has the right set of headings and links in it.\n\nBut, that about page still renders to about-time/index.html.\n\n```\n$ find public -name '*.html' | xargs ls -l\n-rw-rw-r-- 1 mdhender staff 334 Sep 27 15:33 public/about-time/index.html\n-rw-rw-r-- 1 mdhender staff 645 Sep 27 15:33 public/index.html\n-rw-rw-r-- 1 mdhender staff 358 Sep 27 15:33 public/post/first-post/index.html\n-rw-rw-r-- 1 mdhender staff 0 Sep 27 15:33 public/post/index.html\n-rw-rw-r-- 1 mdhender staff 342 Sep 27 15:33 public/post/second-post/index.html\n```\n\nKnowing that hugo is using the slug to generate the file name, the simplest solution is to change the slug. Let's do it the hard way and change the permalink in the configuration file.\n\n```\n$ vi config.toml\n[permalinks]\n\tpage = \"/:title/\"\n\tabout = \"/:filename/\"\n```\n\nGenerate the web site and verify that this didn't work. Hugo lets \"slug\" or \"URL\" override the permalinks setting in the configuration file. Go ahead and comment out the slug in content/about.md, then generate the web site to get it to be created in the right place.\n\n## Sharing Templates\n\nIf you've been following along, you probably noticed that posts have titles in the browser and the home page doesn't. That's because we didn't put the title in the home page's template (layouts/index.html). That's an easy thing to do, but let's look at a different option.\n\nWe can put the common bits into a shared template that's stored in the themes/zafta/layouts/partials/ directory.\n\n### Create the Header and Footer Partials\n\nIn Hugo, a partial is a sugar-coated template. Normally a template reference has a path specified. Partials are different. Hugo searches for them along a TODO defined search path. This makes it easier for end-users to override the theme's presentation.\n\n```\n$ vi themes/zafta/layouts/partials/header.html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n\t\u003ctitle\u003e{{ .Title }}\u003c/title\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n:wq\n\n$ vi themes/zafta/layouts/partials/footer.html\n\u003c/body\u003e\n\u003c/html\u003e\n:wq\n```\n\n### Update the Home Page Template to Use the Partials\n\nThe most noticeable difference between a template call and a partials call is the lack of path:\n\n```\n{{ template \"theme/partials/header.html\" . }}\n```\nversus\n```\n{{ partial \"header.html\" . }}\n```\nBoth pass in the context.\n\nLet's change the home page template to use these new partials.\n\n```\n$ vi themes/zafta/layouts/index.html\n{{ partial \"header.html\" . }}\n\n \u003ch1\u003eposts\u003c/h1\u003e\n {{ range first 10 .Data.Pages }}\n {{ if eq .Type \"post\"}}\n \u003ch2\u003e\u003ca href=\"{{ .Permalink }}\"\u003e{{ .Title }}\u003c/a\u003e\u003c/h2\u003e\n {{ end }}\n {{ end }}\n\n \u003ch1\u003epages\u003c/h1\u003e\n {{ range .Data.Pages }}\n {{ if or (eq .Type \"page\") (eq .Type \"about\") }}\n \u003ch2\u003e\u003ca href=\"{{ .Permalink }}\"\u003e{{ .Type }} - {{ .Title }} - {{ .RelPermalink }}\u003c/a\u003e\u003c/h2\u003e\n {{ end }}\n {{ end }}\n\n{{ partial \"footer.html\" . }}\n:wq\n```\n\nGenerate the web site and verify the results. The title on the home page is now \"your title here\", which comes from the \"title\" variable in the config.toml file.\n\n### Update the Default Single Template to Use the Partials\n\n```\n$ vi themes/zafta/layouts/_default/single.html\n{{ partial \"header.html\" . }}\n\n \u003ch1\u003e{{ .Title }}\u003c/h1\u003e\n {{ .Content }}\n\n{{ partial \"footer.html\" . }}\n:wq\n```\n\nGenerate the web site and verify the results. The title on the posts and the about page should both reflect the value in the markdown file.\n\n## Add “Date Published” to Posts\n\nIt's common to have posts display the date that they were written or published, so let's add that. The front matter of our posts has a variable named \"date.\" It's usually the date the content was created, but let's pretend that's the value we want to display.\n\n### Add “Date Published” to the Template\n\nWe'll start by updating the template used to render the posts. The template code will look like:\n\n```\n{{ .Date.Format \"Mon, Jan 2, 2006\" }}\n```\n\nPosts use the default single template, so we'll change that file.\n\n```\n$ vi themes/zafta/layouts/_default/single.html\n{{ partial \"header.html\" . }}\n\n \u003ch1\u003e{{ .Title }}\u003c/h1\u003e\n \u003ch2\u003e{{ .Date.Format \"Mon, Jan 2, 2006\" }}\u003c/h2\u003e\n {{ .Content }}\n\n{{ partial \"footer.html\" . }}\n:wq\n```\n\nGenerate the web site and verify the results. The posts now have the date displayed in them. There's a problem, though. The \"about\" page also has the date displayed.\n\nAs usual, there are a couple of ways to make the date display only on posts. We could do an \"if\" statement like we did on the home page. Another way would be to create a separate template for posts.\n\nThe \"if\" solution works for sites that have just a couple of content types. It aligns with the principle of \"code for today,\" too.\n\nLet's assume, though, that we've made our site so complex that we feel we have to create a new template type. In Hugo-speak, we're going to create a section template.\n\nLet's restore the default single template before we forget.\n\n```\n$ mkdir themes/zafta/layouts/post\n$ vi themes/zafta/layouts/_default/single.html\n{{ partial \"header.html\" . }}\n\n \u003ch1\u003e{{ .Title }}\u003c/h1\u003e\n {{ .Content }}\n\n{{ partial \"footer.html\" . }}\n:wq\n```\n\nNow we'll update the post's version of the single template. If you remember Hugo's rules, the template engine will use this version over the default.\n\n```\n$ vi themes/zafta/layouts/post/single.html\n{{ partial \"header.html\" . }}\n\n \u003ch1\u003e{{ .Title }}\u003c/h1\u003e\n \u003ch2\u003e{{ .Date.Format \"Mon, Jan 2, 2006\" }}\u003c/h2\u003e\n {{ .Content }}\n\n{{ partial \"footer.html\" . }}\n:wq\n\n```\n\nNote that we removed the date logic from the default template and put it in the post template. Generate the web site and verify the results. Posts have dates and the about page doesn't.\n\n### Don't Repeat Yourself\n\nDRY is a good design goal and Hugo does a great job supporting it. Part of the art of a good template is knowing when to add a new template and when to update an existing one. While you're figuring that out, accept that you'll be doing some refactoring. Hugo makes that easy and fast, so it's okay to delay splitting up a template.\n", - "lastmodified": "2022-12-31T01:56:53.430566995Z", - "tags": null - }, - "/posts/goisforlovers": { + "/features/buttons": { "title": "", - "content": "+++\ntitle = \"(Hu)go Template Primer\"\ndescription = \"\"\ntags = [\n \"go\",\n \"golang\",\n \"templates\",\n \"themes\",\n \"development\",\n]\ndate = \"2014-04-02\"\ncategories = [\n \"Development\",\n \"golang\",\n]\nmenu = \"main\"\n+++\n\nHugo uses the excellent [Go][] [html/template][gohtmltemplate] library for\nits template engine. It is an extremely lightweight engine that provides a very\nsmall amount of logic. In our experience that it is just the right amount of\nlogic to be able to create a good static website. If you have used other\ntemplate systems from different languages or frameworks you will find a lot of\nsimilarities in Go templates.\n\nThis document is a brief primer on using Go templates. The [Go docs][gohtmltemplate]\nprovide more details.\n\n## Introduction to Go Templates\n\nGo templates provide an extremely simple template language. It adheres to the\nbelief that only the most basic of logic belongs in the template or view layer.\nOne consequence of this simplicity is that Go templates parse very quickly.\n\nA unique characteristic of Go templates is they are content aware. Variables and\ncontent will be sanitized depending on the context of where they are used. More\ndetails can be found in the [Go docs][gohtmltemplate].\n\n## Basic Syntax\n\nGolang templates are HTML files with the addition of variables and\nfunctions.\n\n**Go variables and functions are accessible within {{ }}**\n\nAccessing a predefined variable \"foo\":\n\n {{ foo }}\n\n**Parameters are separated using spaces**\n\nCalling the add function with input of 1, 2:\n\n {{ add 1 2 }}\n\n**Methods and fields are accessed via dot notation**\n\nAccessing the Page Parameter \"bar\"\n\n {{ .Params.bar }}\n\n**Parentheses can be used to group items together**\n\n {{ if or (isset .Params \"alt\") (isset .Params \"caption\") }} Caption {{ end }}\n\n\n## Variables\n\nEach Go template has a struct (object) made available to it. In hugo each\ntemplate is passed either a page or a node struct depending on which type of\npage you are rendering. More details are available on the\n[variables](/layout/variables) page.\n\nA variable is accessed by referencing the variable name.\n\n \u003ctitle\u003e{{ .Title }}\u003c/title\u003e\n\nVariables can also be defined and referenced.\n\n {{ $address := \"123 Main St.\"}}\n {{ $address }}\n\n\n## Functions\n\nGo template ship with a few functions which provide basic functionality. The Go\ntemplate system also provides a mechanism for applications to extend the\navailable functions with their own. [Hugo template\nfunctions](/layout/functions) provide some additional functionality we believe\nare useful for building websites. Functions are called by using their name\nfollowed by the required parameters separated by spaces. Template\nfunctions cannot be added without recompiling hugo.\n\n**Example:**\n\n {{ add 1 2 }}\n\n## Includes\n\nWhen including another template you will pass to it the data it will be\nable to access. To pass along the current context please remember to\ninclude a trailing dot. The templates location will always be starting at\nthe /layout/ directory within Hugo.\n\n**Example:**\n\n {{ template \"chrome/header.html\" . }}\n\n\n## Logic\n\nGo templates provide the most basic iteration and conditional logic.\n\n### Iteration\n\nJust like in Go, the Go templates make heavy use of range to iterate over\na map, array or slice. The following are different examples of how to use\nrange.\n\n**Example 1: Using Context**\n\n {{ range array }}\n {{ . }}\n {{ end }}\n\n**Example 2: Declaring value variable name**\n\n {{range $element := array}}\n {{ $element }}\n {{ end }}\n\n**Example 2: Declaring key and value variable name**\n\n {{range $index, $element := array}}\n {{ $index }}\n {{ $element }}\n {{ end }}\n\n### Conditionals\n\nIf, else, with, or, \u0026 and provide the framework for handling conditional\nlogic in Go Templates. Like range, each statement is closed with `end`.\n\n\nGo Templates treat the following values as false:\n\n* false\n* 0\n* any array, slice, map, or string of length zero\n\n**Example 1: If**\n\n {{ if isset .Params \"title\" }}\u003ch4\u003e{{ index .Params \"title\" }}\u003c/h4\u003e{{ end }}\n\n**Example 2: If -\u003e Else**\n\n {{ if isset .Params \"alt\" }}\n {{ index .Params \"alt\" }}\n {{else}}\n {{ index .Params \"caption\" }}\n {{ end }}\n\n**Example 3: And \u0026 Or**\n\n {{ if and (or (isset .Params \"title\") (isset .Params \"caption\")) (isset .Params \"attr\")}}\n\n**Example 4: With**\n\nAn alternative way of writing \"if\" and then referencing the same value\nis to use \"with\" instead. With rebinds the context `.` within its scope,\nand skips the block if the variable is absent.\n\nThe first example above could be simplified as:\n\n {{ with .Params.title }}\u003ch4\u003e{{ . }}\u003c/h4\u003e{{ end }}\n\n**Example 5: If -\u003e Else If**\n\n {{ if isset .Params \"alt\" }}\n {{ index .Params \"alt\" }}\n {{ else if isset .Params \"caption\" }}\n {{ index .Params \"caption\" }}\n {{ end }}\n\n## Pipes\n\nOne of the most powerful components of Go templates is the ability to\nstack actions one after another. This is done by using pipes. Borrowed\nfrom unix pipes, the concept is simple, each pipeline's output becomes the\ninput of the following pipe.\n\nBecause of the very simple syntax of Go templates, the pipe is essential\nto being able to chain together function calls. One limitation of the\npipes is that they only can work with a single value and that value\nbecomes the last parameter of the next pipeline.\n\nA few simple examples should help convey how to use the pipe.\n\n**Example 1 :**\n\n {{ if eq 1 1 }} Same {{ end }}\n\nis the same as\n\n {{ eq 1 1 | if }} Same {{ end }}\n\nIt does look odd to place the if at the end, but it does provide a good\nillustration of how to use the pipes.\n\n**Example 2 :**\n\n {{ index .Params \"disqus_url\" | html }}\n\nAccess the page parameter called \"disqus_url\" and escape the HTML.\n\n**Example 3 :**\n\n {{ if or (or (isset .Params \"title\") (isset .Params \"caption\")) (isset .Params \"attr\")}}\n Stuff Here\n {{ end }}\n\nCould be rewritten as\n\n {{ isset .Params \"caption\" | or isset .Params \"title\" | or isset .Params \"attr\" | if }}\n Stuff Here\n {{ end }}\n\n\n## Context (aka. the dot)\n\nThe most easily overlooked concept to understand about Go templates is that {{ . }}\nalways refers to the current context. In the top level of your template this\nwill be the data set made available to it. Inside of a iteration it will have\nthe value of the current item. When inside of a loop the context has changed. .\nwill no longer refer to the data available to the entire page. If you need to\naccess this from within the loop you will likely want to set it to a variable\ninstead of depending on the context.\n\n**Example:**\n\n {{ $title := .Site.Title }}\n {{ range .Params.tags }}\n \u003cli\u003e \u003ca href=\"{{ $baseurl }}/tags/{{ . | urlize }}\"\u003e{{ . }}\u003c/a\u003e - {{ $title }} \u003c/li\u003e\n {{ end }}\n\nNotice how once we have entered the loop the value of {{ . }} has changed. We\nhave defined a variable outside of the loop so we have access to it from within\nthe loop.\n\n# Hugo Parameters\n\nHugo provides the option of passing values to the template language\nthrough the site configuration (for sitewide values), or through the meta\ndata of each specific piece of content. You can define any values of any\ntype (supported by your front matter/config format) and use them however\nyou want to inside of your templates.\n\n\n## Using Content (page) Parameters\n\nIn each piece of content you can provide variables to be used by the\ntemplates. This happens in the [front matter](/content/front-matter).\n\nAn example of this is used in this documentation site. Most of the pages\nbenefit from having the table of contents provided. Sometimes the TOC just\ndoesn't make a lot of sense. We've defined a variable in our front matter\nof some pages to turn off the TOC from being displayed.\n\nHere is the example front matter:\n\n```\n---\ntitle: \"Permalinks\"\ndate: \"2013-11-18\"\naliases:\n - \"/doc/permalinks/\"\ngroups: [\"extras\"]\ngroups_weight: 30\nnotoc: true\n---\n```\n\nHere is the corresponding code inside of the template:\n\n {{ if not .Params.notoc }}\n \u003cdiv id=\"toc\" class=\"well col-md-4 col-sm-6\"\u003e\n {{ .TableOfContents }}\n \u003c/div\u003e\n {{ end }}\n\n\n\n## Using Site (config) Parameters\nIn your top-level configuration file (eg, `config.yaml`) you can define site\nparameters, which are values which will be available to you in chrome.\n\nFor instance, you might declare:\n\n```yaml\nparams:\n CopyrightHTML: \"Copyright \u0026#xA9; 2013 John Doe. All Rights Reserved.\"\n TwitterUser: \"spf13\"\n SidebarRecentLimit: 5\n```\n\nWithin a footer layout, you might then declare a `\u003cfooter\u003e` which is only\nprovided if the `CopyrightHTML` parameter is provided, and if it is given,\nyou would declare it to be HTML-safe, so that the HTML entity is not escaped\nagain. This would let you easily update just your top-level config file each\nJanuary 1st, instead of hunting through your templates.\n\n```\n{{if .Site.Params.CopyrightHTML}}\u003cfooter\u003e\n\u003cdiv class=\"text-center\"\u003e{{.Site.Params.CopyrightHTML | safeHtml}}\u003c/div\u003e\n\u003c/footer\u003e{{end}}\n```\n\nAn alternative way of writing the \"if\" and then referencing the same value\nis to use \"with\" instead. With rebinds the context `.` within its scope,\nand skips the block if the variable is absent:\n\n```\n{{with .Site.Params.TwitterUser}}\u003cspan class=\"twitter\"\u003e\n\u003ca href=\"https://twitter.com/{{.}}\" rel=\"author\"\u003e\n\u003cimg src=\"/images/twitter.png\" width=\"48\" height=\"48\" title=\"Twitter: {{.}}\"\n alt=\"Twitter\"\u003e\u003c/a\u003e\n\u003c/span\u003e{{end}}\n```\n\nFinally, if you want to pull \"magic constants\" out of your layouts, you can do\nso, such as in this example:\n\n```\n\u003cnav class=\"recent\"\u003e\n \u003ch1\u003eRecent Posts\u003c/h1\u003e\n \u003cul\u003e{{range first .Site.Params.SidebarRecentLimit .Site.Recent}}\n \u003cli\u003e\u003ca href=\"{{.RelPermalink}}\"\u003e{{.Title}}\u003c/a\u003e\u003c/li\u003e\n {{end}}\u003c/ul\u003e\n\u003c/nav\u003e\n```\n\n\n[go]: https://golang.org/\n[gohtmltemplate]: https://golang.org/pkg/html/template/\n", - "lastmodified": "2022-12-31T01:56:53.430566995Z", + "content": "# Buttons\n\nButtons are styled links that can lead to local page or external link.\n\n## Example\n\n```tpl\n{{\u003c/* button relref=\"/\" [class=\"...\"] */\u003e}}Get Home{{\u003c/* /button */\u003e}}\n{{\u003c/* button href=\"https://github.com/alex-shpak/hugo-book\" */\u003e}}Contribute{{\u003c/* /button */\u003e}}\n```\n\n{{\u003c button relref=\"/\" \u003e}}Get Home{{\u003c /button \u003e}}\n{{\u003c button href=\"https://github.com/alex-shpak/hugo-book\" \u003e}}Contribute{{\u003c /button \u003e}}\n", + "lastmodified": "2023-01-05T06:31:25.831295598Z", "tags": null }, - "/posts/hugoisforlovers": { + "/features/callouts": { + "title": "Callouts", + "content": "\n## Callout support\n\nQuartz supports the same Admonition-callout syntax as Obsidian.\n\nThis includes\n- 12 Distinct callout types (each with several aliases)\n- Collapsable callouts\n\nSee [documentation on supported types and syntax here](https://help.obsidian.md/How+to/Use+callouts#Types).\n\n## Showcase\n\n\u003e [!EXAMPLE] Examples\n\u003e\n\u003e Aliases: example\n\n\u003e [!note] Notes\n\u003e\n\u003e Aliases: note\n\n\u003e [!abstract] Summaries \n\u003e\n\u003e Aliases: abstract, summary, tldr\n\n\u003e [!info] Info \n\u003e\n\u003e Aliases: info, todo\n\n\u003e [!tip] Hint \n\u003e\n\u003e Aliases: tip, hint, important\n\n\u003e [!success] Success \n\u003e\n\u003e Aliases: success, check, done\n\n\u003e [!question] Question \n\u003e\n\u003e Aliases: question, help, faq\n\n\u003e [!warning] Warning \n\u003e\n\u003e Aliases: warning, caution, attention\n\n\u003e [!failure] Failure \n\u003e\n\u003e Aliases: failure, fail, missing\n\n\u003e [!danger] Error\n\u003e\n\u003e Aliases: danger, error\n\n\u003e [!bug] Bug\n\u003e\n\u003e Aliases: bug\n\n\u003e [!quote] Quote\n\u003e\n\u003e Aliases: quote, cite\n", + "lastmodified": "2023-01-05T06:51:06.171364064Z", + "tags": null + }, + "/features/columns": { "title": "", - "content": "+++\ntitle = \"Getting Started with Hugo\"\ndescription = \"\"\ntags = [\n \"go\",\n \"golang\",\n \"hugo\",\n \"development\",\n]\ndate = \"2014-04-02\"\ncategories = [\n \"Development\",\n \"golang\",\n]\nmenu = \"main\"\n+++\n\n## Step 1. Install Hugo\n\nGo to [Hugo releases](https://github.com/spf13/hugo/releases) and download the\nappropriate version for your OS and architecture.\n\nSave it somewhere specific as we will be using it in the next step.\n\nMore complete instructions are available at [Install Hugo](https://gohugo.io/getting-started/installing/)\n\n## Step 2. Build the Docs\n\nHugo has its own example site which happens to also be the documentation site\nyou are reading right now.\n\nFollow the following steps:\n\n 1. Clone the [Hugo repository](http://github.com/spf13/hugo)\n 2. Go into the repo\n 3. Run hugo in server mode and build the docs\n 4. Open your browser to http://localhost:1313\n\nCorresponding pseudo commands:\n\n git clone https://github.com/spf13/hugo\n cd hugo\n /path/to/where/you/installed/hugo server --source=./docs\n \u003e 29 pages created\n \u003e 0 tags index created\n \u003e in 27 ms\n \u003e Web Server is available at http://localhost:1313\n \u003e Press ctrl+c to stop\n\nOnce you've gotten here, follow along the rest of this page on your local build.\n\n## Step 3. Change the docs site\n\nStop the Hugo process by hitting Ctrl+C.\n\nNow we are going to run hugo again, but this time with hugo in watch mode.\n\n /path/to/hugo/from/step/1/hugo server --source=./docs --watch\n \u003e 29 pages created\n \u003e 0 tags index created\n \u003e in 27 ms\n \u003e Web Server is available at http://localhost:1313\n \u003e Watching for changes in /Users/spf13/Code/hugo/docs/content\n \u003e Press ctrl+c to stop\n\n\nOpen your [favorite editor](http://vim.spf13.com) and change one of the source\ncontent pages. How about changing this very file to *fix the typo*. How about changing this very file to *fix the typo*.\n\nContent files are found in `docs/content/`. Unless otherwise specified, files\nare located at the same relative location as the url, in our case\n`docs/content/overview/quickstart.md`.\n\nChange and save this file.. Notice what happened in your terminal.\n\n \u003e Change detected, rebuilding site\n\n \u003e 29 pages created\n \u003e 0 tags index created\n \u003e in 26 ms\n\nRefresh the browser and observe that the typo is now fixed.\n\nNotice how quick that was. Try to refresh the site before it's finished building. I double dare you.\nHaving nearly instant feedback enables you to have your creativity flow without waiting for long builds.\n\n## Step 4. Have fun\n\nThe best way to learn something is to play with it.\n", - "lastmodified": "2022-12-31T01:56:53.434566978Z", + "content": "# Columns\n\nColumns help organize shorter pieces of content horizontally for readability.\n\n\n```html\n{{\u003c/* columns */\u003e}} \u003c!-- begin columns block --\u003e\n# Left Content\nLorem markdownum insigne...\n\n\u003c---\u003e \u003c!-- magic separator, between columns --\u003e\n\n# Mid Content\nLorem markdownum insigne...\n\n\u003c---\u003e \u003c!-- magic separator, between columns --\u003e\n\n# Right Content\nLorem markdownum insigne...\n{{\u003c/* /columns */\u003e}}\n```\n\n## Example\n\n{{\u003c columns \u003e}}\n## Left Content\nLorem markdownum insigne. Olympo signis Delphis! Retexi Nereius nova develat\nstringit, frustra Saturnius uteroque inter! Oculis non ritibus Telethusa\nprotulit, sed sed aere valvis inhaesuro Pallas animam: qui _quid_, ignes.\nMiseratus fonte Ditis conubia.\n\n\u003c---\u003e\n\n## Mid Content\nLorem markdownum insigne. Olympo signis Delphis! Retexi Nereius nova develat\nstringit, frustra Saturnius uteroque inter!\n\n\u003c---\u003e\n\n## Right Content\nLorem markdownum insigne. Olympo signis Delphis! Retexi Nereius nova develat\nstringit, frustra Saturnius uteroque inter! Oculis non ritibus Telethusa\nprotulit, sed sed aere valvis inhaesuro Pallas animam: qui _quid_, ignes.\nMiseratus fonte Ditis conubia.\n{{\u003c /columns \u003e}}\n", + "lastmodified": "2023-01-05T06:31:25.831295598Z", "tags": null }, - "/posts/migrate-from-jekyll": { - "title": "Migrate to Hugo from Jekyll", - "content": "\n## Move static content to `static`\nJekyll has a rule that any directory not starting with `_` will be copied as-is to the `_site` output. Hugo keeps all static content under `static`. You should therefore move it all there.\nWith Jekyll, something that looked like\n\n ▾ \u003croot\u003e/\n ▾ images/\n logo.png\n\nshould become\n\n ▾ \u003croot\u003e/\n ▾ static/\n ▾ images/\n logo.png\n\nAdditionally, you'll want any files that should reside at the root (such as `CNAME`) to be moved to `static`.\n\n## Create your Hugo configuration file\nHugo can read your configuration as JSON, YAML or TOML. Hugo supports parameters custom configuration too. Refer to the [Hugo configuration documentation](/overview/configuration/) for details.\n\n## Set your configuration publish folder to `_site`\nThe default is for Jekyll to publish to `_site` and for Hugo to publish to `public`. If, like me, you have [`_site` mapped to a git submodule on the `gh-pages` branch](http://blog.blindgaenger.net/generate_github_pages_in_a_submodule.html), you'll want to do one of two alternatives:\n\n1. Change your submodule to point to map `gh-pages` to public instead of `_site` (recommended).\n\n git submodule deinit _site\n git rm _site\n git submodule add -b gh-pages git@github.com:your-username/your-repo.git public\n\n2. Or, change the Hugo configuration to use `_site` instead of `public`.\n\n {\n ..\n \"publishdir\": \"_site\",\n ..\n }\n\n## Convert Jekyll templates to Hugo templates\nThat's the bulk of the work right here. The documentation is your friend. You should refer to [Jekyll's template documentation](http://jekyllrb.com/docs/templates/) if you need to refresh your memory on how you built your blog and [Hugo's template](/layout/templates/) to learn Hugo's way.\n\nAs a single reference data point, converting my templates for [heyitsalex.net](http://heyitsalex.net/) took me no more than a few hours.\n\n## Convert Jekyll plugins to Hugo shortcodes\nJekyll has [plugins](http://jekyllrb.com/docs/plugins/); Hugo has [shortcodes](/doc/shortcodes/). It's fairly trivial to do a port.\n\n### Implementation\nAs an example, I was using a custom [`image_tag`](https://github.com/alexandre-normand/alexandre-normand/blob/74bb12036a71334fdb7dba84e073382fc06908ec/_plugins/image_tag.rb) plugin to generate figures with caption when running Jekyll. As I read about shortcodes, I found Hugo had a nice built-in shortcode that does exactly the same thing.\n\nJekyll's plugin:\n\n module Jekyll\n class ImageTag \u003c Liquid::Tag\n @url = nil\n @caption = nil\n @class = nil\n @link = nil\n // Patterns\n IMAGE_URL_WITH_CLASS_AND_CAPTION =\n IMAGE_URL_WITH_CLASS_AND_CAPTION_AND_LINK = /(\\w+)(\\s+)((https?:\\/\\/|\\/)(\\S+))(\\s+)\"(.*?)\"(\\s+)-\u003e((https?:\\/\\/|\\/)(\\S+))(\\s*)/i\n IMAGE_URL_WITH_CAPTION = /((https?:\\/\\/|\\/)(\\S+))(\\s+)\"(.*?)\"/i\n IMAGE_URL_WITH_CLASS = /(\\w+)(\\s+)((https?:\\/\\/|\\/)(\\S+))/i\n IMAGE_URL = /((https?:\\/\\/|\\/)(\\S+))/i\n def initialize(tag_name, markup, tokens)\n super\n if markup =~ IMAGE_URL_WITH_CLASS_AND_CAPTION_AND_LINK\n @class = $1\n @url = $3\n @caption = $7\n @link = $9\n elsif markup =~ IMAGE_URL_WITH_CLASS_AND_CAPTION\n @class = $1\n @url = $3\n @caption = $7\n elsif markup =~ IMAGE_URL_WITH_CAPTION\n @url = $1\n @caption = $5\n elsif markup =~ IMAGE_URL_WITH_CLASS\n @class = $1\n @url = $3\n elsif markup =~ IMAGE_URL\n @url = $1\n end\n end\n def render(context)\n if @class\n source = \"\u003cfigure class='#{@class}'\u003e\"\n else\n source = \"\u003cfigure\u003e\"\n end\n if @link\n source += \"\u003ca href=\\\"#{@link}\\\"\u003e\"\n end\n source += \"\u003cimg src=\\\"#{@url}\\\"\u003e\"\n if @link\n source += \"\u003c/a\u003e\"\n end\n source += \"\u003cfigcaption\u003e#{@caption}\u003c/figcaption\u003e\" if @caption\n source += \"\u003c/figure\u003e\"\n source\n end\n end\n end\n Liquid::Template.register_tag('image', Jekyll::ImageTag)\n\nis written as this Hugo shortcode:\n\n \u003c!-- image --\u003e\n \u003cfigure {{ with .Get \"class\" }}class=\"{{.}}\"{{ end }}\u003e\n {{ with .Get \"link\"}}\u003ca href=\"{{.}}\"\u003e{{ end }}\n \u003cimg src=\"{{ .Get \"src\" }}\" {{ if or (.Get \"alt\") (.Get \"caption\") }}alt=\"{{ with .Get \"alt\"}}{{.}}{{else}}{{ .Get \"caption\" }}{{ end }}\"{{ end }} /\u003e\n {{ if .Get \"link\"}}\u003c/a\u003e{{ end }}\n {{ if or (or (.Get \"title\") (.Get \"caption\")) (.Get \"attr\")}}\n \u003cfigcaption\u003e{{ if isset .Params \"title\" }}\n {{ .Get \"title\" }}{{ end }}\n {{ if or (.Get \"caption\") (.Get \"attr\")}}\u003cp\u003e\n {{ .Get \"caption\" }}\n {{ with .Get \"attrlink\"}}\u003ca href=\"{{.}}\"\u003e {{ end }}\n {{ .Get \"attr\" }}\n {{ if .Get \"attrlink\"}}\u003c/a\u003e {{ end }}\n \u003c/p\u003e {{ end }}\n \u003c/figcaption\u003e\n {{ end }}\n \u003c/figure\u003e\n \u003c!-- image --\u003e\n\n### Usage\nI simply changed:\n\n {% image full http://farm5.staticflickr.com/4136/4829260124_57712e570a_o_d.jpg \"One of my favorite touristy-type photos. I secretly waited for the good light while we were \"having fun\" and took this. Only regret: a stupid pole in the top-left corner of the frame I had to clumsily get rid of at post-processing.\" -\u003ehttp://www.flickr.com/photos/alexnormand/4829260124/in/set-72157624547713078/ %}\n\nto this (this example uses a slightly extended version named `fig`, different than the built-in `figure`):\n\n {{%/* fig class=\"full\" src=\"http://farm5.staticflickr.com/4136/4829260124_57712e570a_o_d.jpg\" title=\"One of my favorite touristy-type photos. I secretly waited for the good light while we were having fun and took this. Only regret: a stupid pole in the top-left corner of the frame I had to clumsily get rid of at post-processing.\" link=\"http://www.flickr.com/photos/alexnormand/4829260124/in/set-72157624547713078/\" */%}}\n\nAs a bonus, the shortcode named parameters are, arguably, more readable.\n\n## Finishing touches\n### Fix content\nDepending on the amount of customization that was done with each post with Jekyll, this step will require more or less effort. There are no hard and fast rules here except that `hugo server --watch` is your friend. Test your changes and fix errors as needed.\n\n### Clean up\nYou'll want to remove the Jekyll configuration at this point. If you have anything else that isn't used, delete it.\n\n## A practical example in a diff\n[Hey, it's Alex](http://heyitsalex.net/) was migrated in less than a _father-with-kids day_ from Jekyll to Hugo. You can see all the changes (and screw-ups) by looking at this [diff](https://github.com/alexandre-normand/alexandre-normand/compare/869d69435bd2665c3fbf5b5c78d4c22759d7613a...b7f6605b1265e83b4b81495423294208cc74d610).\n", - "lastmodified": "2022-12-31T01:56:53.434566978Z", + "/features/details": { + "title": "", + "content": "# Details\n\nDetails shortcode is a helper for `details` html5 element. It is going to replace `expand` shortcode.\n\n## Example\n```tpl\n{{\u003c/* details \"Title\" [open] */\u003e}}\n## Markdown content\nLorem markdownum insigne...\n{{\u003c/* /details */\u003e}}\n```\n```tpl\n{{\u003c/* details title=\"Title\" open=true */\u003e}}\n## Markdown content\nLorem markdownum insigne...\n{{\u003c/* /details */\u003e}}\n```\n\n{{\u003c details \"Title\" open \u003e}}\n## Markdown content\nLorem markdownum insigne...\n{{\u003c /details \u003e}}\n", + "lastmodified": "2023-01-05T06:31:25.831295598Z", + "tags": null + }, + "/features/expand": { + "title": "", + "content": "# Expand\n\nExpand shortcode can help to decrease clutter on screen by hiding part of text. Expand content by clicking on it.\n\n## Example\n### Default\n\n```tpl\n{{\u003c/* expand */\u003e}}\n## Markdown content\nLorem markdownum insigne...\n{{\u003c/* /expand */\u003e}}\n```\n\n{{\u003c expand \u003e}}\n## Markdown content\nLorem markdownum insigne...\n{{\u003c /expand \u003e}}\n\n### With Custom Label\n\n```tpl\n{{\u003c/* expand \"Custom Label\" \"...\" */\u003e}}\n## Markdown content\nLorem markdownum insigne...\n{{\u003c/* /expand */\u003e}}\n```\n\n{{\u003c expand \"Custom Label\" \"...\" \u003e}}\n## Markdown content\nLorem markdownum insigne. Olympo signis Delphis! Retexi Nereius nova develat\nstringit, frustra Saturnius uteroque inter! Oculis non ritibus Telethusa\nprotulit, sed sed aere valvis inhaesuro Pallas animam: qui _quid_, ignes.\nMiseratus fonte Ditis conubia.\n{{\u003c /expand \u003e}}\n", + "lastmodified": "2023-01-05T06:31:25.831295598Z", + "tags": null + }, + "/features/languages": { + "title": "Chinese, Japanese, Korean Support (测试)", + "content": "\n## Chinese, Japanese, Korean Support\n几乎在我们意识到之前,我们已经离开了地面。\n\n우리가 그것을 알기도 전에 우리는 땅을 떠났습니다.\n\n私たちがそれを知るほぼ前に、私たちは地面を離れていました。\n\n## RTL\nMore information on configuring RTL languages like Arabic in the [config](notes/config.md) page.\n", + "lastmodified": "2023-01-05T06:49:42.120137696Z", + "tags": null + }, + "/features/latex": { + "title": "LaTeX", + "content": "\nBlock math works with two dollar signs `$$...$$`\n\n$$f(x) = \\int_{-\\infty}^\\infty\n f\\hat(\\xi),e^{2 \\pi i \\xi x}\n \\,d\\xi$$\n\t\nInline math also works with single dollar signs `$...$`. For example, Euler's identity but inline: $e^{i\\pi} = -1$\n\nAligned equations work quite well:\n\n$$\n\\begin{aligned}\na \u0026= b + c \\\\ \u0026= e + f \\\\\n\\end{aligned}\n$$\n\nAnd matrices\n\n$$\n\\begin{bmatrix}\n1 \u0026 2 \u0026 3 \\\\\na \u0026 b \u0026 c\n\\end{bmatrix}\n$$", + "lastmodified": "2023-01-05T06:49:47.80008656Z", + "tags": null + }, + "/features/mermaid": { + "title": "", + "content": "# Mermaid Chart\n\n[MermaidJS](https://mermaid-js.github.io/) is library for generating svg charts and diagrams from text.\n\n{{\u003c hint info \u003e}}\n**Override Mermaid Initialization Config**\n\nTo override the [initialization config](https://mermaid-js.github.io/mermaid/#/Setup) for Mermaid,\ncreate a `mermaid.json` file in your `assets` folder!\n{{\u003c /hint \u003e}}\n\n## Example\n\n{{\u003c columns \u003e}}\n```tpl\n{{\u003c/*/* mermaid [class=\"text-center\"]*/*/\u003e}}\nstateDiagram-v2\n State1: The state with a note\n note right of State1\n Important information! You can write\n notes.\n end note\n State1 --\u003e State2\n note left of State2 : This is the note to the left.\n{{\u003c/*/* /mermaid */*/\u003e}}\n```\n\n\u003c---\u003e\n\n{{\u003c mermaid \u003e}}\nstateDiagram-v2\n State1: The state with a note\n note right of State1\n Important information! You can write\n notes.\n end note\n State1 --\u003e State2\n note left of State2 : This is the note to the left.\n{{\u003c /mermaid \u003e}}\n\n{{\u003c /columns \u003e}}\n", + "lastmodified": "2023-01-05T06:31:25.831295598Z", + "tags": null + }, + "/features/section/": { + "title": "", + "content": "\n# Section\n\nSection renders pages in section as definition list, using title and description.\n\n## Example\n\n```tpl\n{{\u003c/* section */\u003e}}\n```\n\n{{\u003csection\u003e}}\n", + "lastmodified": "2023-01-05T06:31:25.83529555Z", + "tags": null + }, + "/features/section/first-page": { + "title": "", + "content": "# First page\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. \n\n\u003c!--more--\u003e\nDuis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n", + "lastmodified": "2023-01-05T06:31:25.83529555Z", + "tags": null + }, + "/features/section/second-page": { + "title": "", + "content": "# Second Page\nLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n\n\u003c!--more--\u003e\nDuis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n\n", + "lastmodified": "2023-01-05T06:31:25.83529555Z", + "tags": null + }, + "/features/tabs": { + "title": "", + "content": "# Tabs\n\nTabs let you organize content by context, for example installation instructions for each supported platform.\n\n```tpl\n{{\u003c/* tabs \"uniqueid\" */\u003e}}\n{{\u003c/* tab \"MacOS\" */\u003e}} # MacOS Content {{\u003c/* /tab */\u003e}}\n{{\u003c/* tab \"Linux\" */\u003e}} # Linux Content {{\u003c/* /tab */\u003e}}\n{{\u003c/* tab \"Windows\" */\u003e}} # Windows Content {{\u003c/* /tab */\u003e}}\n{{\u003c/* /tabs */\u003e}}\n```\n\n## Example\n\n{{\u003c tabs \"uniqueid\" \u003e}}\n{{\u003c tab \"MacOS\" \u003e}}\n# MacOS\n\nThis is tab **MacOS** content.\n\nLorem markdownum insigne. Olympo signis Delphis! Retexi Nereius nova develat\nstringit, frustra Saturnius uteroque inter! Oculis non ritibus Telethusa\nprotulit, sed sed aere valvis inhaesuro Pallas animam: qui _quid_, ignes.\nMiseratus fonte Ditis conubia.\n{{\u003c /tab \u003e}}\n\n{{\u003c tab \"Linux\" \u003e}}\n\n# Linux\n\nThis is tab **Linux** content.\n\nLorem markdownum insigne. Olympo signis Delphis! Retexi Nereius nova develat\nstringit, frustra Saturnius uteroque inter! Oculis non ritibus Telethusa\nprotulit, sed sed aere valvis inhaesuro Pallas animam: qui _quid_, ignes.\nMiseratus fonte Ditis conubia.\n{{\u003c /tab \u003e}}\n\n{{\u003c tab \"Windows\" \u003e}}\n\n# Windows\n\nThis is tab **Windows** content.\n\nLorem markdownum insigne. Olympo signis Delphis! Retexi Nereius nova develat\nstringit, frustra Saturnius uteroque inter! Oculis non ritibus Telethusa\nprotulit, sed sed aere valvis inhaesuro Pallas animam: qui _quid_, ignes.\nMiseratus fonte Ditis conubia.\n{{\u003c /tab \u003e}}\n{{\u003c /tabs \u003e}}\n", + "lastmodified": "2023-01-05T06:31:25.83529555Z", "tags": null } } \ No newline at end of file diff --git a/assets/indices/linkIndex.json b/assets/indices/linkIndex.json index 88f1a81..c926484 100644 --- a/assets/indices/linkIndex.json +++ b/assets/indices/linkIndex.json @@ -58,228 +58,1460 @@ "text": "notes/foo/footest" } ], - "/notes/CJK-+-Latex-Support-%E6%B5%8B%E8%AF%95": [ + "/configuration/config": [ { - "source": "/notes/CJK-+-Latex-Support-%E6%B5%8B%E8%AF%95", - "target": "/notes/config", - "text": "config" - } - ], - "/notes/config": [ - { - "source": "/notes/config", + "source": "/configuration/config", "target": "/notes/troubleshooting", "text": "FAQ and Troubleshooting guide" }, { - "source": "/notes/config", + "source": "/configuration/config", "target": "/notes/CJK-+-Latex-Support-%E6%B5%8B%E8%AF%95", "text": "CJK + Latex Support (测试)" } ], - "/notes/docker": [ + "/configuration/docker": [ { - "source": "/notes/docker", + "source": "/configuration/docker", "target": "/notes/preview-changes", "text": "install Quartz's dependencies manually" } ], - "/notes/editing": [ + "/configuration/editing": [ { - "source": "/notes/editing", + "source": "/configuration/editing", "target": "/notes/obsidian", "text": "How to setup your Obsidian Vault to work with Quartz" }, { - "source": "/notes/editing", + "source": "/configuration/editing", "target": "/notes/preview-changes", "text": "Preview Quartz Changes" }, { - "source": "/notes/editing", + "source": "/configuration/editing", "target": "/notes/hosting", "text": "Hosting Quartz online!" }, { - "source": "/notes/editing", + "source": "/configuration/editing", "target": "/notes/troubleshooting", "text": "FAQ and Troubleshooting guide" } ], - "/notes/hosting": [ + "/configuration/hosting": [ { - "source": "/notes/hosting", + "source": "/configuration/hosting", "target": "/notes/custom-Domain", "text": "Learn how to set it up with Quartz" }, { - "source": "/notes/hosting", + "source": "/configuration/hosting", "target": "/notes/ignore-notes", "text": "Excluding pages from being published" }, { - "source": "/notes/hosting", + "source": "/configuration/hosting", "target": "/notes/docker", "text": "Docker" }, { - "source": "/notes/hosting", + "source": "/configuration/hosting", "target": "/notes/config", "text": "Customizing Quartz" }, { - "source": "/notes/hosting", + "source": "/configuration/hosting", "target": "/notes/troubleshooting", "text": "FAQ and Troubleshooting guide" } ], - "/notes/obsidian": [ + "/configuration/obsidian": [ { - "source": "/notes/obsidian", + "source": "/configuration/obsidian", "target": "/notes/setup", "text": "setup" }, { - "source": "/notes/obsidian", + "source": "/configuration/obsidian", "target": "/notes/preview-changes", "text": "Preview Quartz Changes" } ], - "/notes/preview-changes": [ + "/configuration/preview-changes": [ { - "source": "/notes/preview-changes", + "source": "/configuration/preview-changes", "target": "/notes/hosting", "text": "Hosting Quartz online!" } ], - "/notes/setup": [ + "/configuration/setup": [ { - "source": "/notes/setup", + "source": "/configuration/setup", "target": "/notes/editing", "text": "Editing Notes in Quartz" }, { - "source": "/notes/setup", + "source": "/configuration/setup", "target": "/notes/troubleshooting", "text": "FAQ and Troubleshooting guide" } ], - "/notes/troubleshooting": [ + "/configuration/troubleshooting": [ { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/CJK-+-Latex-Support-%E6%B5%8B%E8%AF%95", "text": "CJK + Latex Support (测试)" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/hosting", "text": "hosting" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/ignore-notes", "text": "excluding pages from being published" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/hosting", "text": "hosting" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/obsidian", "text": "Obsidian" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/editing", "text": "the 'how to edit' guide" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/hosting", "text": "the hosting guide" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/config", "text": "customization guide" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/editing", "text": "local editing" } ], - "/posts/goisforlovers": [ + "/cs61b/": [ { - "source": "/posts/goisforlovers", - "target": "/layout/variables", - "text": "variables" + "source": "/cs61b/", + "target": "/oop/access-control", + "text": "Access Control" }, { - "source": "/posts/goisforlovers", - "target": "/layout/functions", - "text": "Hugo template\nfunctions" + "source": "/cs61b/", + "target": "/oop/dynamic-method-selection", + "text": "Dynamic Method Selection" }, { - "source": "/posts/goisforlovers", - "target": "/content/front-matter", - "text": "front matter" + "source": "/cs61b/", + "target": "/oop/generics", + "text": "Generic Types" + }, + { + "source": "/cs61b/", + "target": "/asymptotics/asymptotics-practice", + "text": "Asymptotics Practice" + }, + { + "source": "/cs61b/", + "target": "/abstract-data-types/union-find-disjoint-sets", + "text": "Union Find (Disjoint Sets)" + }, + { + "source": "/cs61b/", + "target": "/abstract-data-types/collections/stacks-and-queues", + "text": "Stacks and Queues" + }, + { + "source": "/cs61b/", + "target": "/abstract-data-types/collections/linked-lists", + "text": "Linked Lists" + }, + { + "source": "/cs61b/", + "target": "/abstract-data-types/collections/sets", + "text": "Sets" + }, + { + "source": "/cs61b/", + "target": "/sorting/sorting-basics", + "text": "Sorting" + }, + { + "source": "/cs61b/", + "target": "/algorithms/searching/", + "text": "Searching" + }, + { + "source": "/cs61b/", + "target": "/algorithms/searching/binary-search", + "text": "Binary Search" + }, + { + "source": "/cs61b/", + "target": "/algorithms/shortest-paths/", + "text": "Shortest Paths" + }, + { + "source": "/cs61b/", + "target": "/misc-topics/exceptions", + "text": "Exceptions" } ], - "/posts/migrate-from-jekyll": [ + "/cs61b/SUMMARY": [ { - "source": "/posts/migrate-from-jekyll", - "target": "/overview/configuration/", - "text": "Hugo configuration documentation" + "source": "/cs61b/SUMMARY", + "target": "/CS61B-Index", + "text": "Welcome" }, { - "source": "/posts/migrate-from-jekyll", - "target": "/layout/templates/", - "text": "Hugo's template" + "source": "/cs61b/SUMMARY", + "target": "/oop/inheritance", + "text": "Inheritance" }, { - "source": "/posts/migrate-from-jekyll", - "target": "/doc/shortcodes/", - "text": "shortcodes" + "source": "/cs61b/SUMMARY", + "target": "/oop/access-control", + "text": "Access Control" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/oop/dynamic-method-selection", + "text": "Dynamic Method Selection" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/oop/objects", + "text": "Java Objects" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/oop/generics", + "text": "Generic Types" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/asymptotics/asymptotics", + "text": "Asymptotic Analysis Basics" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/asymptotics/amortization", + "text": "Amortization" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/asymptotics/asymptotics-practice", + "text": "Asymptotics Practice" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/collections/README", + "text": "Collections" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/collections/arrays", + "text": "Arrays" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/collections/linked-lists", + "text": "Linked Lists" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/collections/sets", + "text": "Sets" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/collections/stacks-and-queues", + "text": "Stacks and Queues" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/binary-trees/README", + "text": "Binary Trees" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/binary-trees/heaps", + "text": "Heaps" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/binary-trees/balanced-search-structures", + "text": "Balanced BSTs" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/binary-trees/tries", + "text": "Tries" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/graphs", + "text": "Graphs" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/hashing", + "text": "Hashing and Hash Tables" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/union-find-disjoint-sets", + "text": "Union Find (Disjoint Sets)" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/comparables-and-comparators", + "text": "Comparables and Comparators" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/sorting/sorting-basics", + "text": "Sorting" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/minimax", + "text": "Minimax Algorithm" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/searching/README", + "text": "Searching" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/searching/binary-search", + "text": "Binary Search" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/searching/depth-first-search-dfs", + "text": "Depth First Search (DFS)" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/searching/breadth-first-search-bfs", + "text": "Breadth First Search (BFS)" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/shortest-paths/README", + "text": "Shortest Paths" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/shortest-paths/dijkstras-algorithm", + "text": "Dijkstra's Algorithm" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/shortest-paths/a-search", + "text": "A* Search" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/minimum-spanning-trees/README", + "text": "Minimum Spanning Trees" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/minimum-spanning-trees/prims-algorithm", + "text": "Prim's Algorithm" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/minimum-spanning-trees/kruskals-algorithm", + "text": "Kruskal's Algorithm" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/misc-topics/modular-arithmetic", + "text": "Modular Arithmetic and Bit Manipulation" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/misc-topics/exceptions", + "text": "Exceptions" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/misc-topics/more-resources", + "text": "More Resources" + } + ], + "/cs61b/abstract-data-types/binary-trees/README": [ + { + "source": "/cs61b/abstract-data-types/binary-trees/README", + "target": "/../../algorithms/searching/binary-search", + "text": "binary-search.md" + }, + { + "source": "/cs61b/abstract-data-types/binary-trees/README", + "target": "/balanced-search-structures", + "text": "Balanced BSTs" + }, + { + "source": "/cs61b/abstract-data-types/binary-trees/README", + "target": "/../graphs", + "text": "Graphs" + }, + { + "source": "/cs61b/abstract-data-types/binary-trees/README", + "target": "/tries", + "text": "Tries" + }, + { + "source": "/cs61b/abstract-data-types/binary-trees/README", + "target": "/../hashing", + "text": "Hash Tables" + }, + { + "source": "/cs61b/abstract-data-types/binary-trees/README", + "target": "/../../algorithms/searching/depth-first-search-dfs", + "text": "depth-first-search-dfs.md" + }, + { + "source": "/cs61b/abstract-data-types/binary-trees/README", + "target": "/../../algorithms/searching/breadth-first-search-bfs", + "text": "breadth-first-search-bfs.md" + } + ], + "/cs61b/abstract-data-types/binary-trees/balanced-search-structures": [ + { + "source": "/cs61b/abstract-data-types/binary-trees/balanced-search-structures", + "target": "/./", + "text": "Binary Trees" + } + ], + "/cs61b/abstract-data-types/binary-trees/tries": [ + { + "source": "/cs61b/abstract-data-types/binary-trees/tries", + "target": "/../hashing", + "text": "Hashing and Hash Tables" + }, + { + "source": "/cs61b/abstract-data-types/binary-trees/tries", + "target": "/../collections/sets", + "text": "Sets" + } + ], + "/cs61b/abstract-data-types/collections/README": [ + { + "source": "/cs61b/abstract-data-types/collections/README", + "target": "/arrays", + "text": "ArrayLists" + }, + { + "source": "/cs61b/abstract-data-types/collections/README", + "target": "/linked-lists", + "text": "Linked Lists" + }, + { + "source": "/cs61b/abstract-data-types/collections/README", + "target": "/sets", + "text": "Sets" + }, + { + "source": "/cs61b/abstract-data-types/collections/README", + "target": "/../hashing", + "text": "Hashing and Hash Tables" + }, + { + "source": "/cs61b/abstract-data-types/collections/README", + "target": "/stacks-and-queues", + "text": "Stacks and Queues" + } + ], + "/cs61b/abstract-data-types/collections/arrays": [ + { + "source": "/cs61b/abstract-data-types/collections/arrays", + "target": "/../../oop/objects", + "text": "Java Objects" + }, + { + "source": "/cs61b/abstract-data-types/collections/arrays", + "target": "/../../asymptotics/amortization", + "text": "Amortization" + }, + { + "source": "/cs61b/abstract-data-types/collections/arrays", + "target": "/../../oop/generics", + "text": "Generic Types" + }, + { + "source": "/cs61b/abstract-data-types/collections/arrays", + "target": "/./", + "text": "Collections" + } + ], + "/cs61b/abstract-data-types/collections/linked-lists": [ + { + "source": "/cs61b/abstract-data-types/collections/linked-lists", + "target": "/arrays", + "text": "Arrays" + } + ], + "/cs61b/abstract-data-types/collections/sets": [ + { + "source": "/cs61b/abstract-data-types/collections/sets", + "target": "/../../asymptotics/amortization", + "text": "resized" + } + ], + "/cs61b/abstract-data-types/collections/stacks-and-queues": [ + { + "source": "/cs61b/abstract-data-types/collections/stacks-and-queues", + "target": "/../../algorithms/shortest-paths/dijkstras-algorithm", + "text": "finding shortest paths using Dijkstra's Algorithm" + }, + { + "source": "/cs61b/abstract-data-types/collections/stacks-and-queues", + "target": "/stacks-and-queues", + "text": "Priority Queues" + } + ], + "/cs61b/abstract-data-types/graphs": [ + { + "source": "/cs61b/abstract-data-types/graphs", + "target": "/../algorithms/searching/depth-first-search-dfs", + "text": "Depth First Search (DFS)" + }, + { + "source": "/cs61b/abstract-data-types/graphs", + "target": "/../algorithms/searching/breadth-first-search-bfs", + "text": "Breadth First Search (BFS)" + }, + { + "source": "/cs61b/abstract-data-types/graphs", + "target": "/../algorithms/minimum-spanning-trees/", + "text": "Minimum Spanning Trees" + }, + { + "source": "/cs61b/abstract-data-types/graphs", + "target": "/../algorithms/shortest-paths/", + "text": "Shortest Paths" + }, + { + "source": "/cs61b/abstract-data-types/graphs", + "target": "/../algorithms/shortest-paths/dijkstras-algorithm", + "text": "Dijkstra's Algorithm" + }, + { + "source": "/cs61b/abstract-data-types/graphs", + "target": "/../algorithms/shortest-paths/a-search", + "text": "A* Search" + }, + { + "source": "/cs61b/abstract-data-types/graphs", + "target": "/../algorithms/minimum-spanning-trees/prims-algorithm", + "text": "Prim's Algorithm" + }, + { + "source": "/cs61b/abstract-data-types/graphs", + "target": "/../algorithms/minimum-spanning-trees/kruskals-algorithm", + "text": "Kruskal's Algorithm" + } + ], + "/cs61b/abstract-data-types/hashing": [ + { + "source": "/cs61b/abstract-data-types/hashing", + "target": "/../asymptotics/amortization", + "text": "Amortization" + } + ], + "/cs61b/abstract-data-types/union-find-disjoint-sets": [ + { + "source": "/cs61b/abstract-data-types/union-find-disjoint-sets", + "target": "/../algorithms/minimum-spanning-trees/kruskals-algorithm", + "text": "Kruskal's Algorithm" + } + ], + "/cs61b/algorithms/minimum-spanning-trees/kruskals-algorithm": [ + { + "source": "/cs61b/algorithms/minimum-spanning-trees/kruskals-algorithm", + "target": "/./", + "text": "Minimum Spanning Trees" + }, + { + "source": "/cs61b/algorithms/minimum-spanning-trees/kruskals-algorithm", + "target": "/../../abstract-data-types/union-find-disjoint-sets", + "text": "Union Find (Disjoint Sets)" + }, + { + "source": "/cs61b/algorithms/minimum-spanning-trees/kruskals-algorithm", + "target": "/../../abstract-data-types/union-find-disjoint-sets", + "text": "Union Find (Disjoint Sets)" + }, + { + "source": "/cs61b/algorithms/minimum-spanning-trees/kruskals-algorithm", + "target": "/../../abstract-data-types/collections/stacks-and-queues", + "text": "PriorityQueue" + } + ], + "/cs61b/algorithms/minimum-spanning-trees/prims-algorithm": [ + { + "source": "/cs61b/algorithms/minimum-spanning-trees/prims-algorithm", + "target": "/./README", + "text": "Minimum Spanning Trees" + }, + { + "source": "/cs61b/algorithms/minimum-spanning-trees/prims-algorithm", + "target": "/../../abstract-data-types/collections/stacks-and-queues", + "text": "PriorityQueue" + }, + { + "source": "/cs61b/algorithms/minimum-spanning-trees/prims-algorithm", + "target": "/../shortest-paths/dijkstras-algorithm", + "text": "Dijkstra's" + } + ], + "/cs61b/algorithms/searching/README": [ + { + "source": "/cs61b/algorithms/searching/README", + "target": "/binary-search", + "text": "binary-search.md" + }, + { + "source": "/cs61b/algorithms/searching/README", + "target": "/depth-first-search-dfs", + "text": "depth-first-search-dfs.md" + }, + { + "source": "/cs61b/algorithms/searching/README", + "target": "/breadth-first-search-bfs", + "text": "breadth-first-search-bfs.md" + } + ], + "/cs61b/algorithms/searching/binary-search": [ + { + "source": "/cs61b/algorithms/searching/binary-search", + "target": "/../../abstract-data-types/binary-trees/", + "text": "binary trees" + } + ], + "/cs61b/algorithms/searching/breadth-first-search-bfs": [ + { + "source": "/cs61b/algorithms/searching/breadth-first-search-bfs", + "target": "/depth-first-search-dfs", + "text": "Depth First Search (DFS)" + }, + { + "source": "/cs61b/algorithms/searching/breadth-first-search-bfs", + "target": "/../shortest-paths/dijkstras-algorithm", + "text": "Dijkstra's Algorithm" + } + ], + "/cs61b/algorithms/shortest-paths/a-search": [ + { + "source": "/cs61b/algorithms/shortest-paths/a-search", + "target": "/dijkstras-algorithm", + "text": "Dijkstra's Algorithm" + } + ], + "/cs61b/algorithms/shortest-paths/dijkstras-algorithm": [ + { + "source": "/cs61b/algorithms/shortest-paths/dijkstras-algorithm", + "target": "/../../abstract-data-types/graphs", + "text": "Graphs" + }, + { + "source": "/cs61b/algorithms/shortest-paths/dijkstras-algorithm", + "target": "/../../abstract-data-types/collections/stacks-and-queues", + "text": "Stacks and Queues" + }, + { + "source": "/cs61b/algorithms/shortest-paths/dijkstras-algorithm", + "target": "/./", + "text": "Shortest Paths" + } + ], + "/cs61b/asymptotics/amortization": [ + { + "source": "/cs61b/asymptotics/amortization", + "target": "/asymptotics", + "text": "Asymptotic Analysis Basics" + } + ], + "/cs61b/asymptotics/asymptotics": [ + { + "source": "/cs61b/asymptotics/asymptotics", + "target": "/asymptotics-practice", + "text": "try some problems!" + }, + { + "source": "/cs61b/asymptotics/asymptotics", + "target": "/asymptotics", + "text": "Simplify" + } + ], + "/cs61b/asymptotics/asymptotics-practice": [ + { + "source": "/cs61b/asymptotics/asymptotics-practice", + "target": "/asymptotics", + "text": "Asymptotic Analysis Basics" + } + ], + "/cs61b/misc-topics/modular-arithmetic": [ + { + "source": "/cs61b/misc-topics/modular-arithmetic", + "target": "/../oop/objects", + "text": "Java Objects" + } + ], + "/cs61b/oop/dynamic-method-selection": [ + { + "source": "/cs61b/oop/dynamic-method-selection", + "target": "/inheritance", + "text": "inheritance" + }, + { + "source": "/cs61b/oop/dynamic-method-selection", + "target": "/access-control", + "text": "access control" + }, + { + "source": "/cs61b/oop/dynamic-method-selection", + "target": "/inheritance", + "text": "Interfaces" + }, + { + "source": "/cs61b/oop/dynamic-method-selection", + "target": "/../abstract-data-types/collections/", + "text": "Collections" + } + ], + "/cs61b/oop/generics": [ + { + "source": "/cs61b/oop/generics", + "target": "/dynamic-method-selection", + "text": "Dynamic Method Selection" + }, + { + "source": "/cs61b/oop/generics", + "target": "/inheritance", + "text": "inheritance rules" + } + ], + "/cs61b/oop/inheritance": [ + { + "source": "/cs61b/oop/inheritance", + "target": "/access-control", + "text": "Access Control" + }, + { + "source": "/cs61b/oop/inheritance", + "target": "/objects", + "text": "References, Objects, and Types in Java" + }, + { + "source": "/cs61b/oop/inheritance", + "target": "/generics", + "text": "Generic Types" + }, + { + "source": "/cs61b/oop/inheritance", + "target": "/dynamic-method-selection", + "text": "Dynamic Method Selection" + } + ], + "/cs61b/oop/objects": [ + { + "source": "/cs61b/oop/objects", + "target": "/../misc-topics/modular-arithmetic", + "text": "Modular Arithmetic and Bit Manipulation" + }, + { + "source": "/cs61b/oop/objects", + "target": "/../abstract-data-types/collections/", + "text": "collections" + } + ], + "/features/languages": [ + { + "source": "/features/languages", + "target": "/notes/config", + "text": "config" } ] }, "backlinks": { - "/content/front-matter": [ + "/../../abstract-data-types/binary-trees/": [ { - "source": "/posts/goisforlovers", - "target": "/content/front-matter", - "text": "front matter" + "source": "/cs61b/algorithms/searching/binary-search", + "target": "/../../abstract-data-types/binary-trees/", + "text": "binary trees" } ], - "/doc/shortcodes/": [ + "/../../abstract-data-types/collections/stacks-and-queues": [ { - "source": "/posts/migrate-from-jekyll", - "target": "/doc/shortcodes/", - "text": "shortcodes" + "source": "/cs61b/algorithms/minimum-spanning-trees/kruskals-algorithm", + "target": "/../../abstract-data-types/collections/stacks-and-queues", + "text": "PriorityQueue" + }, + { + "source": "/cs61b/algorithms/minimum-spanning-trees/prims-algorithm", + "target": "/../../abstract-data-types/collections/stacks-and-queues", + "text": "PriorityQueue" + }, + { + "source": "/cs61b/algorithms/shortest-paths/dijkstras-algorithm", + "target": "/../../abstract-data-types/collections/stacks-and-queues", + "text": "Stacks and Queues" } ], - "/layout/functions": [ + "/../../abstract-data-types/graphs": [ { - "source": "/posts/goisforlovers", - "target": "/layout/functions", - "text": "Hugo template\nfunctions" + "source": "/cs61b/algorithms/shortest-paths/dijkstras-algorithm", + "target": "/../../abstract-data-types/graphs", + "text": "Graphs" } ], - "/layout/templates/": [ + "/../../abstract-data-types/union-find-disjoint-sets": [ { - "source": "/posts/migrate-from-jekyll", - "target": "/layout/templates/", - "text": "Hugo's template" + "source": "/cs61b/algorithms/minimum-spanning-trees/kruskals-algorithm", + "target": "/../../abstract-data-types/union-find-disjoint-sets", + "text": "Union Find (Disjoint Sets)" + }, + { + "source": "/cs61b/algorithms/minimum-spanning-trees/kruskals-algorithm", + "target": "/../../abstract-data-types/union-find-disjoint-sets", + "text": "Union Find (Disjoint Sets)" } ], - "/layout/variables": [ + "/../../algorithms/searching/binary-search": [ { - "source": "/posts/goisforlovers", - "target": "/layout/variables", - "text": "variables" + "source": "/cs61b/abstract-data-types/binary-trees/README", + "target": "/../../algorithms/searching/binary-search", + "text": "binary-search.md" + } + ], + "/../../algorithms/searching/breadth-first-search-bfs": [ + { + "source": "/cs61b/abstract-data-types/binary-trees/README", + "target": "/../../algorithms/searching/breadth-first-search-bfs", + "text": "breadth-first-search-bfs.md" + } + ], + "/../../algorithms/searching/depth-first-search-dfs": [ + { + "source": "/cs61b/abstract-data-types/binary-trees/README", + "target": "/../../algorithms/searching/depth-first-search-dfs", + "text": "depth-first-search-dfs.md" + } + ], + "/../../algorithms/shortest-paths/dijkstras-algorithm": [ + { + "source": "/cs61b/abstract-data-types/collections/stacks-and-queues", + "target": "/../../algorithms/shortest-paths/dijkstras-algorithm", + "text": "finding shortest paths using Dijkstra's Algorithm" + } + ], + "/../../asymptotics/amortization": [ + { + "source": "/cs61b/abstract-data-types/collections/arrays", + "target": "/../../asymptotics/amortization", + "text": "Amortization" + }, + { + "source": "/cs61b/abstract-data-types/collections/sets", + "target": "/../../asymptotics/amortization", + "text": "resized" + } + ], + "/../../oop/generics": [ + { + "source": "/cs61b/abstract-data-types/collections/arrays", + "target": "/../../oop/generics", + "text": "Generic Types" + } + ], + "/../../oop/objects": [ + { + "source": "/cs61b/abstract-data-types/collections/arrays", + "target": "/../../oop/objects", + "text": "Java Objects" + } + ], + "/../abstract-data-types/collections/": [ + { + "source": "/cs61b/oop/dynamic-method-selection", + "target": "/../abstract-data-types/collections/", + "text": "Collections" + }, + { + "source": "/cs61b/oop/objects", + "target": "/../abstract-data-types/collections/", + "text": "collections" + } + ], + "/../algorithms/minimum-spanning-trees/": [ + { + "source": "/cs61b/abstract-data-types/graphs", + "target": "/../algorithms/minimum-spanning-trees/", + "text": "Minimum Spanning Trees" + } + ], + "/../algorithms/minimum-spanning-trees/kruskals-algorithm": [ + { + "source": "/cs61b/abstract-data-types/graphs", + "target": "/../algorithms/minimum-spanning-trees/kruskals-algorithm", + "text": "Kruskal's Algorithm" + }, + { + "source": "/cs61b/abstract-data-types/union-find-disjoint-sets", + "target": "/../algorithms/minimum-spanning-trees/kruskals-algorithm", + "text": "Kruskal's Algorithm" + } + ], + "/../algorithms/minimum-spanning-trees/prims-algorithm": [ + { + "source": "/cs61b/abstract-data-types/graphs", + "target": "/../algorithms/minimum-spanning-trees/prims-algorithm", + "text": "Prim's Algorithm" + } + ], + "/../algorithms/searching/breadth-first-search-bfs": [ + { + "source": "/cs61b/abstract-data-types/graphs", + "target": "/../algorithms/searching/breadth-first-search-bfs", + "text": "Breadth First Search (BFS)" + } + ], + "/../algorithms/searching/depth-first-search-dfs": [ + { + "source": "/cs61b/abstract-data-types/graphs", + "target": "/../algorithms/searching/depth-first-search-dfs", + "text": "Depth First Search (DFS)" + } + ], + "/../algorithms/shortest-paths/": [ + { + "source": "/cs61b/abstract-data-types/graphs", + "target": "/../algorithms/shortest-paths/", + "text": "Shortest Paths" + } + ], + "/../algorithms/shortest-paths/a-search": [ + { + "source": "/cs61b/abstract-data-types/graphs", + "target": "/../algorithms/shortest-paths/a-search", + "text": "A* Search" + } + ], + "/../algorithms/shortest-paths/dijkstras-algorithm": [ + { + "source": "/cs61b/abstract-data-types/graphs", + "target": "/../algorithms/shortest-paths/dijkstras-algorithm", + "text": "Dijkstra's Algorithm" + } + ], + "/../asymptotics/amortization": [ + { + "source": "/cs61b/abstract-data-types/hashing", + "target": "/../asymptotics/amortization", + "text": "Amortization" + } + ], + "/../collections/sets": [ + { + "source": "/cs61b/abstract-data-types/binary-trees/tries", + "target": "/../collections/sets", + "text": "Sets" + } + ], + "/../graphs": [ + { + "source": "/cs61b/abstract-data-types/binary-trees/README", + "target": "/../graphs", + "text": "Graphs" + } + ], + "/../hashing": [ + { + "source": "/cs61b/abstract-data-types/binary-trees/README", + "target": "/../hashing", + "text": "Hash Tables" + }, + { + "source": "/cs61b/abstract-data-types/binary-trees/tries", + "target": "/../hashing", + "text": "Hashing and Hash Tables" + }, + { + "source": "/cs61b/abstract-data-types/collections/README", + "target": "/../hashing", + "text": "Hashing and Hash Tables" + } + ], + "/../misc-topics/modular-arithmetic": [ + { + "source": "/cs61b/oop/objects", + "target": "/../misc-topics/modular-arithmetic", + "text": "Modular Arithmetic and Bit Manipulation" + } + ], + "/../oop/objects": [ + { + "source": "/cs61b/misc-topics/modular-arithmetic", + "target": "/../oop/objects", + "text": "Java Objects" + } + ], + "/../shortest-paths/dijkstras-algorithm": [ + { + "source": "/cs61b/algorithms/minimum-spanning-trees/prims-algorithm", + "target": "/../shortest-paths/dijkstras-algorithm", + "text": "Dijkstra's" + }, + { + "source": "/cs61b/algorithms/searching/breadth-first-search-bfs", + "target": "/../shortest-paths/dijkstras-algorithm", + "text": "Dijkstra's Algorithm" + } + ], + "/./": [ + { + "source": "/cs61b/abstract-data-types/binary-trees/balanced-search-structures", + "target": "/./", + "text": "Binary Trees" + }, + { + "source": "/cs61b/abstract-data-types/collections/arrays", + "target": "/./", + "text": "Collections" + }, + { + "source": "/cs61b/algorithms/minimum-spanning-trees/kruskals-algorithm", + "target": "/./", + "text": "Minimum Spanning Trees" + }, + { + "source": "/cs61b/algorithms/shortest-paths/dijkstras-algorithm", + "target": "/./", + "text": "Shortest Paths" + } + ], + "/./README": [ + { + "source": "/cs61b/algorithms/minimum-spanning-trees/prims-algorithm", + "target": "/./README", + "text": "Minimum Spanning Trees" + } + ], + "/CS61B-Index": [ + { + "source": "/cs61b/SUMMARY", + "target": "/CS61B-Index", + "text": "Welcome" + } + ], + "/abstract-data-types/binary-trees/README": [ + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/binary-trees/README", + "text": "Binary Trees" + } + ], + "/abstract-data-types/binary-trees/balanced-search-structures": [ + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/binary-trees/balanced-search-structures", + "text": "Balanced BSTs" + } + ], + "/abstract-data-types/binary-trees/heaps": [ + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/binary-trees/heaps", + "text": "Heaps" + } + ], + "/abstract-data-types/binary-trees/tries": [ + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/binary-trees/tries", + "text": "Tries" + } + ], + "/abstract-data-types/collections/README": [ + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/collections/README", + "text": "Collections" + } + ], + "/abstract-data-types/collections/arrays": [ + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/collections/arrays", + "text": "Arrays" + } + ], + "/abstract-data-types/collections/linked-lists": [ + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/collections/linked-lists", + "text": "Linked Lists" + }, + { + "source": "/cs61b/", + "target": "/abstract-data-types/collections/linked-lists", + "text": "Linked Lists" + } + ], + "/abstract-data-types/collections/sets": [ + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/collections/sets", + "text": "Sets" + }, + { + "source": "/cs61b/", + "target": "/abstract-data-types/collections/sets", + "text": "Sets" + } + ], + "/abstract-data-types/collections/stacks-and-queues": [ + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/collections/stacks-and-queues", + "text": "Stacks and Queues" + }, + { + "source": "/cs61b/", + "target": "/abstract-data-types/collections/stacks-and-queues", + "text": "Stacks and Queues" + } + ], + "/abstract-data-types/comparables-and-comparators": [ + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/comparables-and-comparators", + "text": "Comparables and Comparators" + } + ], + "/abstract-data-types/graphs": [ + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/graphs", + "text": "Graphs" + } + ], + "/abstract-data-types/hashing": [ + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/hashing", + "text": "Hashing and Hash Tables" + } + ], + "/abstract-data-types/union-find-disjoint-sets": [ + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/union-find-disjoint-sets", + "text": "Union Find (Disjoint Sets)" + }, + { + "source": "/cs61b/", + "target": "/abstract-data-types/union-find-disjoint-sets", + "text": "Union Find (Disjoint Sets)" + } + ], + "/access-control": [ + { + "source": "/cs61b/oop/dynamic-method-selection", + "target": "/access-control", + "text": "access control" + }, + { + "source": "/cs61b/oop/inheritance", + "target": "/access-control", + "text": "Access Control" + } + ], + "/algorithms/minimax": [ + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/minimax", + "text": "Minimax Algorithm" + } + ], + "/algorithms/minimum-spanning-trees/README": [ + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/minimum-spanning-trees/README", + "text": "Minimum Spanning Trees" + } + ], + "/algorithms/minimum-spanning-trees/kruskals-algorithm": [ + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/minimum-spanning-trees/kruskals-algorithm", + "text": "Kruskal's Algorithm" + } + ], + "/algorithms/minimum-spanning-trees/prims-algorithm": [ + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/minimum-spanning-trees/prims-algorithm", + "text": "Prim's Algorithm" + } + ], + "/algorithms/searching/": [ + { + "source": "/cs61b/", + "target": "/algorithms/searching/", + "text": "Searching" + } + ], + "/algorithms/searching/README": [ + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/searching/README", + "text": "Searching" + } + ], + "/algorithms/searching/binary-search": [ + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/searching/binary-search", + "text": "Binary Search" + }, + { + "source": "/cs61b/", + "target": "/algorithms/searching/binary-search", + "text": "Binary Search" + } + ], + "/algorithms/searching/breadth-first-search-bfs": [ + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/searching/breadth-first-search-bfs", + "text": "Breadth First Search (BFS)" + } + ], + "/algorithms/searching/depth-first-search-dfs": [ + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/searching/depth-first-search-dfs", + "text": "Depth First Search (DFS)" + } + ], + "/algorithms/shortest-paths/": [ + { + "source": "/cs61b/", + "target": "/algorithms/shortest-paths/", + "text": "Shortest Paths" + } + ], + "/algorithms/shortest-paths/README": [ + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/shortest-paths/README", + "text": "Shortest Paths" + } + ], + "/algorithms/shortest-paths/a-search": [ + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/shortest-paths/a-search", + "text": "A* Search" + } + ], + "/algorithms/shortest-paths/dijkstras-algorithm": [ + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/shortest-paths/dijkstras-algorithm", + "text": "Dijkstra's Algorithm" + } + ], + "/arrays": [ + { + "source": "/cs61b/abstract-data-types/collections/README", + "target": "/arrays", + "text": "ArrayLists" + }, + { + "source": "/cs61b/abstract-data-types/collections/linked-lists", + "target": "/arrays", + "text": "Arrays" + } + ], + "/asymptotics": [ + { + "source": "/cs61b/asymptotics/amortization", + "target": "/asymptotics", + "text": "Asymptotic Analysis Basics" + }, + { + "source": "/cs61b/asymptotics/asymptotics-practice", + "target": "/asymptotics", + "text": "Asymptotic Analysis Basics" + }, + { + "source": "/cs61b/asymptotics/asymptotics", + "target": "/asymptotics", + "text": "Simplify" + } + ], + "/asymptotics-practice": [ + { + "source": "/cs61b/asymptotics/asymptotics", + "target": "/asymptotics-practice", + "text": "try some problems!" + } + ], + "/asymptotics/amortization": [ + { + "source": "/cs61b/SUMMARY", + "target": "/asymptotics/amortization", + "text": "Amortization" + } + ], + "/asymptotics/asymptotics": [ + { + "source": "/cs61b/SUMMARY", + "target": "/asymptotics/asymptotics", + "text": "Asymptotic Analysis Basics" + } + ], + "/asymptotics/asymptotics-practice": [ + { + "source": "/cs61b/SUMMARY", + "target": "/asymptotics/asymptotics-practice", + "text": "Asymptotics Practice" + }, + { + "source": "/cs61b/", + "target": "/asymptotics/asymptotics-practice", + "text": "Asymptotics Practice" + } + ], + "/balanced-search-structures": [ + { + "source": "/cs61b/abstract-data-types/binary-trees/README", + "target": "/balanced-search-structures", + "text": "Balanced BSTs" + } + ], + "/binary-search": [ + { + "source": "/cs61b/algorithms/searching/README", + "target": "/binary-search", + "text": "binary-search.md" + } + ], + "/breadth-first-search-bfs": [ + { + "source": "/cs61b/algorithms/searching/README", + "target": "/breadth-first-search-bfs", + "text": "breadth-first-search-bfs.md" + } + ], + "/depth-first-search-dfs": [ + { + "source": "/cs61b/algorithms/searching/README", + "target": "/depth-first-search-dfs", + "text": "depth-first-search-dfs.md" + }, + { + "source": "/cs61b/algorithms/searching/breadth-first-search-bfs", + "target": "/depth-first-search-dfs", + "text": "Depth First Search (DFS)" + } + ], + "/dijkstras-algorithm": [ + { + "source": "/cs61b/algorithms/shortest-paths/a-search", + "target": "/dijkstras-algorithm", + "text": "Dijkstra's Algorithm" + } + ], + "/dynamic-method-selection": [ + { + "source": "/cs61b/oop/generics", + "target": "/dynamic-method-selection", + "text": "Dynamic Method Selection" + }, + { + "source": "/cs61b/oop/inheritance", + "target": "/dynamic-method-selection", + "text": "Dynamic Method Selection" + } + ], + "/generics": [ + { + "source": "/cs61b/oop/inheritance", + "target": "/generics", + "text": "Generic Types" + } + ], + "/inheritance": [ + { + "source": "/cs61b/oop/dynamic-method-selection", + "target": "/inheritance", + "text": "inheritance" + }, + { + "source": "/cs61b/oop/dynamic-method-selection", + "target": "/inheritance", + "text": "Interfaces" + }, + { + "source": "/cs61b/oop/generics", + "target": "/inheritance", + "text": "inheritance rules" + } + ], + "/linked-lists": [ + { + "source": "/cs61b/abstract-data-types/collections/README", + "target": "/linked-lists", + "text": "Linked Lists" + } + ], + "/misc-topics/exceptions": [ + { + "source": "/cs61b/SUMMARY", + "target": "/misc-topics/exceptions", + "text": "Exceptions" + }, + { + "source": "/cs61b/", + "target": "/misc-topics/exceptions", + "text": "Exceptions" + } + ], + "/misc-topics/modular-arithmetic": [ + { + "source": "/cs61b/SUMMARY", + "target": "/misc-topics/modular-arithmetic", + "text": "Modular Arithmetic and Bit Manipulation" + } + ], + "/misc-topics/more-resources": [ + { + "source": "/cs61b/SUMMARY", + "target": "/misc-topics/more-resources", + "text": "More Resources" } ], "/notes/CJK-+-Latex-Support-%E6%B5%8B%E8%AF%95": [ @@ -289,12 +1521,12 @@ "text": "CJK + Latex Support" }, { - "source": "/notes/config", + "source": "/configuration/config", "target": "/notes/CJK-+-Latex-Support-%E6%B5%8B%E8%AF%95", "text": "CJK + Latex Support (测试)" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/CJK-+-Latex-Support-%E6%B5%8B%E8%AF%95", "text": "CJK + Latex Support (测试)" } @@ -308,48 +1540,48 @@ ], "/notes/config": [ { - "source": "/notes/CJK-+-Latex-Support-%E6%B5%8B%E8%AF%95", - "target": "/notes/config", - "text": "config" - }, - { - "source": "/notes/hosting", + "source": "/configuration/hosting", "target": "/notes/config", "text": "Customizing Quartz" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/config", "text": "customization guide" + }, + { + "source": "/features/languages", + "target": "/notes/config", + "text": "config" } ], "/notes/custom-Domain": [ { - "source": "/notes/hosting", + "source": "/configuration/hosting", "target": "/notes/custom-Domain", "text": "Learn how to set it up with Quartz" } ], "/notes/docker": [ { - "source": "/notes/hosting", + "source": "/configuration/hosting", "target": "/notes/docker", "text": "Docker" } ], "/notes/editing": [ { - "source": "/notes/setup", + "source": "/configuration/setup", "target": "/notes/editing", "text": "Editing Notes in Quartz" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/editing", "text": "the 'how to edit' guide" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/editing", "text": "local editing" } @@ -370,51 +1602,51 @@ ], "/notes/hosting": [ { - "source": "/notes/editing", + "source": "/configuration/editing", "target": "/notes/hosting", "text": "Hosting Quartz online!" }, { - "source": "/notes/preview-changes", + "source": "/configuration/preview-changes", "target": "/notes/hosting", "text": "Hosting Quartz online!" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/hosting", "text": "hosting" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/hosting", "text": "hosting" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/hosting", "text": "the hosting guide" } ], "/notes/ignore-notes": [ { - "source": "/notes/hosting", + "source": "/configuration/hosting", "target": "/notes/ignore-notes", "text": "Excluding pages from being published" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/ignore-notes", "text": "excluding pages from being published" } ], "/notes/obsidian": [ { - "source": "/notes/editing", + "source": "/configuration/editing", "target": "/notes/obsidian", "text": "How to setup your Obsidian Vault to work with Quartz" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/obsidian", "text": "Obsidian" } @@ -428,17 +1660,17 @@ ], "/notes/preview-changes": [ { - "source": "/notes/docker", + "source": "/configuration/docker", "target": "/notes/preview-changes", "text": "install Quartz's dependencies manually" }, { - "source": "/notes/editing", + "source": "/configuration/editing", "target": "/notes/preview-changes", "text": "Preview Quartz Changes" }, { - "source": "/notes/obsidian", + "source": "/configuration/obsidian", "target": "/notes/preview-changes", "text": "Preview Quartz Changes" } @@ -457,7 +1689,7 @@ "text": "Setup your own digital garden using Quartz" }, { - "source": "/notes/obsidian", + "source": "/configuration/obsidian", "target": "/notes/setup", "text": "setup" } @@ -476,22 +1708,22 @@ "text": "Troubleshooting and FAQ" }, { - "source": "/notes/config", + "source": "/configuration/config", "target": "/notes/troubleshooting", "text": "FAQ and Troubleshooting guide" }, { - "source": "/notes/editing", + "source": "/configuration/editing", "target": "/notes/troubleshooting", "text": "FAQ and Troubleshooting guide" }, { - "source": "/notes/hosting", + "source": "/configuration/hosting", "target": "/notes/troubleshooting", "text": "FAQ and Troubleshooting guide" }, { - "source": "/notes/setup", + "source": "/configuration/setup", "target": "/notes/troubleshooting", "text": "FAQ and Troubleshooting guide" } @@ -503,11 +1735,92 @@ "text": "update" } ], - "/overview/configuration/": [ + "/objects": [ { - "source": "/posts/migrate-from-jekyll", - "target": "/overview/configuration/", - "text": "Hugo configuration documentation" + "source": "/cs61b/oop/inheritance", + "target": "/objects", + "text": "References, Objects, and Types in Java" + } + ], + "/oop/access-control": [ + { + "source": "/cs61b/SUMMARY", + "target": "/oop/access-control", + "text": "Access Control" + }, + { + "source": "/cs61b/", + "target": "/oop/access-control", + "text": "Access Control" + } + ], + "/oop/dynamic-method-selection": [ + { + "source": "/cs61b/SUMMARY", + "target": "/oop/dynamic-method-selection", + "text": "Dynamic Method Selection" + }, + { + "source": "/cs61b/", + "target": "/oop/dynamic-method-selection", + "text": "Dynamic Method Selection" + } + ], + "/oop/generics": [ + { + "source": "/cs61b/SUMMARY", + "target": "/oop/generics", + "text": "Generic Types" + }, + { + "source": "/cs61b/", + "target": "/oop/generics", + "text": "Generic Types" + } + ], + "/oop/inheritance": [ + { + "source": "/cs61b/SUMMARY", + "target": "/oop/inheritance", + "text": "Inheritance" + } + ], + "/oop/objects": [ + { + "source": "/cs61b/SUMMARY", + "target": "/oop/objects", + "text": "Java Objects" + } + ], + "/sets": [ + { + "source": "/cs61b/abstract-data-types/collections/README", + "target": "/sets", + "text": "Sets" + } + ], + "/sorting/sorting-basics": [ + { + "source": "/cs61b/SUMMARY", + "target": "/sorting/sorting-basics", + "text": "Sorting" + }, + { + "source": "/cs61b/", + "target": "/sorting/sorting-basics", + "text": "Sorting" + } + ], + "/stacks-and-queues": [ + { + "source": "/cs61b/abstract-data-types/collections/README", + "target": "/stacks-and-queues", + "text": "Stacks and Queues" + }, + { + "source": "/cs61b/abstract-data-types/collections/stacks-and-queues", + "target": "/stacks-and-queues", + "text": "Priority Queues" } ], "/tags/setup": [ @@ -516,6 +1829,13 @@ "target": "/tags/setup", "text": "setup-related notes" } + ], + "/tries": [ + { + "source": "/cs61b/abstract-data-types/binary-trees/README", + "target": "/tries", + "text": "Tries" + } ] } }, @@ -576,169 +1896,724 @@ "text": "notes/foo/footest" }, { - "source": "/notes/CJK-+-Latex-Support-%E6%B5%8B%E8%AF%95", - "target": "/notes/config", - "text": "config" - }, - { - "source": "/notes/config", + "source": "/configuration/config", "target": "/notes/troubleshooting", "text": "FAQ and Troubleshooting guide" }, { - "source": "/notes/config", + "source": "/configuration/config", "target": "/notes/CJK-+-Latex-Support-%E6%B5%8B%E8%AF%95", "text": "CJK + Latex Support (测试)" }, { - "source": "/notes/docker", + "source": "/configuration/docker", "target": "/notes/preview-changes", "text": "install Quartz's dependencies manually" }, { - "source": "/notes/editing", + "source": "/configuration/editing", "target": "/notes/obsidian", "text": "How to setup your Obsidian Vault to work with Quartz" }, { - "source": "/notes/editing", + "source": "/configuration/editing", "target": "/notes/preview-changes", "text": "Preview Quartz Changes" }, { - "source": "/notes/editing", + "source": "/configuration/editing", "target": "/notes/hosting", "text": "Hosting Quartz online!" }, { - "source": "/notes/editing", + "source": "/configuration/editing", "target": "/notes/troubleshooting", "text": "FAQ and Troubleshooting guide" }, { - "source": "/notes/hosting", + "source": "/configuration/hosting", "target": "/notes/custom-Domain", "text": "Learn how to set it up with Quartz" }, { - "source": "/notes/hosting", + "source": "/configuration/hosting", "target": "/notes/ignore-notes", "text": "Excluding pages from being published" }, { - "source": "/notes/hosting", + "source": "/configuration/hosting", "target": "/notes/docker", "text": "Docker" }, { - "source": "/notes/hosting", + "source": "/configuration/hosting", "target": "/notes/config", "text": "Customizing Quartz" }, { - "source": "/notes/hosting", + "source": "/configuration/hosting", "target": "/notes/troubleshooting", "text": "FAQ and Troubleshooting guide" }, { - "source": "/notes/obsidian", + "source": "/configuration/obsidian", "target": "/notes/setup", "text": "setup" }, { - "source": "/notes/obsidian", + "source": "/configuration/obsidian", "target": "/notes/preview-changes", "text": "Preview Quartz Changes" }, { - "source": "/notes/preview-changes", + "source": "/configuration/preview-changes", "target": "/notes/hosting", "text": "Hosting Quartz online!" }, { - "source": "/notes/setup", + "source": "/configuration/setup", "target": "/notes/editing", "text": "Editing Notes in Quartz" }, { - "source": "/notes/setup", + "source": "/configuration/setup", "target": "/notes/troubleshooting", "text": "FAQ and Troubleshooting guide" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/CJK-+-Latex-Support-%E6%B5%8B%E8%AF%95", "text": "CJK + Latex Support (测试)" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/hosting", "text": "hosting" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/ignore-notes", "text": "excluding pages from being published" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/hosting", "text": "hosting" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/obsidian", "text": "Obsidian" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/editing", "text": "the 'how to edit' guide" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/hosting", "text": "the hosting guide" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/config", "text": "customization guide" }, { - "source": "/notes/troubleshooting", + "source": "/configuration/troubleshooting", "target": "/notes/editing", "text": "local editing" }, { - "source": "/posts/goisforlovers", - "target": "/layout/variables", - "text": "variables" + "source": "/cs61b/SUMMARY", + "target": "/CS61B-Index", + "text": "Welcome" }, { - "source": "/posts/goisforlovers", - "target": "/layout/functions", - "text": "Hugo template\nfunctions" + "source": "/cs61b/SUMMARY", + "target": "/oop/inheritance", + "text": "Inheritance" }, { - "source": "/posts/goisforlovers", - "target": "/content/front-matter", - "text": "front matter" + "source": "/cs61b/SUMMARY", + "target": "/oop/access-control", + "text": "Access Control" }, { - "source": "/posts/migrate-from-jekyll", - "target": "/overview/configuration/", - "text": "Hugo configuration documentation" + "source": "/cs61b/SUMMARY", + "target": "/oop/dynamic-method-selection", + "text": "Dynamic Method Selection" }, { - "source": "/posts/migrate-from-jekyll", - "target": "/layout/templates/", - "text": "Hugo's template" + "source": "/cs61b/SUMMARY", + "target": "/oop/objects", + "text": "Java Objects" }, { - "source": "/posts/migrate-from-jekyll", - "target": "/doc/shortcodes/", - "text": "shortcodes" + "source": "/cs61b/SUMMARY", + "target": "/oop/generics", + "text": "Generic Types" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/asymptotics/asymptotics", + "text": "Asymptotic Analysis Basics" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/asymptotics/amortization", + "text": "Amortization" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/asymptotics/asymptotics-practice", + "text": "Asymptotics Practice" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/collections/README", + "text": "Collections" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/collections/arrays", + "text": "Arrays" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/collections/linked-lists", + "text": "Linked Lists" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/collections/sets", + "text": "Sets" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/collections/stacks-and-queues", + "text": "Stacks and Queues" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/binary-trees/README", + "text": "Binary Trees" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/binary-trees/heaps", + "text": "Heaps" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/binary-trees/balanced-search-structures", + "text": "Balanced BSTs" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/binary-trees/tries", + "text": "Tries" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/graphs", + "text": "Graphs" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/hashing", + "text": "Hashing and Hash Tables" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/union-find-disjoint-sets", + "text": "Union Find (Disjoint Sets)" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/abstract-data-types/comparables-and-comparators", + "text": "Comparables and Comparators" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/sorting/sorting-basics", + "text": "Sorting" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/minimax", + "text": "Minimax Algorithm" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/searching/README", + "text": "Searching" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/searching/binary-search", + "text": "Binary Search" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/searching/depth-first-search-dfs", + "text": "Depth First Search (DFS)" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/searching/breadth-first-search-bfs", + "text": "Breadth First Search (BFS)" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/shortest-paths/README", + "text": "Shortest Paths" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/shortest-paths/dijkstras-algorithm", + "text": "Dijkstra's Algorithm" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/shortest-paths/a-search", + "text": "A* Search" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/minimum-spanning-trees/README", + "text": "Minimum Spanning Trees" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/minimum-spanning-trees/prims-algorithm", + "text": "Prim's Algorithm" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/algorithms/minimum-spanning-trees/kruskals-algorithm", + "text": "Kruskal's Algorithm" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/misc-topics/modular-arithmetic", + "text": "Modular Arithmetic and Bit Manipulation" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/misc-topics/exceptions", + "text": "Exceptions" + }, + { + "source": "/cs61b/SUMMARY", + "target": "/misc-topics/more-resources", + "text": "More Resources" + }, + { + "source": "/cs61b/", + "target": "/oop/access-control", + "text": "Access Control" + }, + { + "source": "/cs61b/", + "target": "/oop/dynamic-method-selection", + "text": "Dynamic Method Selection" + }, + { + "source": "/cs61b/", + "target": "/oop/generics", + "text": "Generic Types" + }, + { + "source": "/cs61b/", + "target": "/asymptotics/asymptotics-practice", + "text": "Asymptotics Practice" + }, + { + "source": "/cs61b/", + "target": "/abstract-data-types/union-find-disjoint-sets", + "text": "Union Find (Disjoint Sets)" + }, + { + "source": "/cs61b/", + "target": "/abstract-data-types/collections/stacks-and-queues", + "text": "Stacks and Queues" + }, + { + "source": "/cs61b/", + "target": "/abstract-data-types/collections/linked-lists", + "text": "Linked Lists" + }, + { + "source": "/cs61b/", + "target": "/abstract-data-types/collections/sets", + "text": "Sets" + }, + { + "source": "/cs61b/", + "target": "/sorting/sorting-basics", + "text": "Sorting" + }, + { + "source": "/cs61b/", + "target": "/algorithms/searching/", + "text": "Searching" + }, + { + "source": "/cs61b/", + "target": "/algorithms/searching/binary-search", + "text": "Binary Search" + }, + { + "source": "/cs61b/", + "target": "/algorithms/shortest-paths/", + "text": "Shortest Paths" + }, + { + "source": "/cs61b/", + "target": "/misc-topics/exceptions", + "text": "Exceptions" + }, + { + "source": "/cs61b/abstract-data-types/binary-trees/README", + "target": "/../../algorithms/searching/binary-search", + "text": "binary-search.md" + }, + { + "source": "/cs61b/abstract-data-types/binary-trees/README", + "target": "/balanced-search-structures", + "text": "Balanced BSTs" + }, + { + "source": "/cs61b/abstract-data-types/binary-trees/README", + "target": "/../graphs", + "text": "Graphs" + }, + { + "source": "/cs61b/abstract-data-types/binary-trees/README", + "target": "/tries", + "text": "Tries" + }, + { + "source": "/cs61b/abstract-data-types/binary-trees/README", + "target": "/../hashing", + "text": "Hash Tables" + }, + { + "source": "/cs61b/abstract-data-types/binary-trees/README", + "target": "/../../algorithms/searching/depth-first-search-dfs", + "text": "depth-first-search-dfs.md" + }, + { + "source": "/cs61b/abstract-data-types/binary-trees/README", + "target": "/../../algorithms/searching/breadth-first-search-bfs", + "text": "breadth-first-search-bfs.md" + }, + { + "source": "/cs61b/abstract-data-types/binary-trees/balanced-search-structures", + "target": "/./", + "text": "Binary Trees" + }, + { + "source": "/cs61b/abstract-data-types/binary-trees/tries", + "target": "/../hashing", + "text": "Hashing and Hash Tables" + }, + { + "source": "/cs61b/abstract-data-types/binary-trees/tries", + "target": "/../collections/sets", + "text": "Sets" + }, + { + "source": "/cs61b/abstract-data-types/collections/README", + "target": "/arrays", + "text": "ArrayLists" + }, + { + "source": "/cs61b/abstract-data-types/collections/README", + "target": "/linked-lists", + "text": "Linked Lists" + }, + { + "source": "/cs61b/abstract-data-types/collections/README", + "target": "/sets", + "text": "Sets" + }, + { + "source": "/cs61b/abstract-data-types/collections/README", + "target": "/../hashing", + "text": "Hashing and Hash Tables" + }, + { + "source": "/cs61b/abstract-data-types/collections/README", + "target": "/stacks-and-queues", + "text": "Stacks and Queues" + }, + { + "source": "/cs61b/abstract-data-types/collections/arrays", + "target": "/../../oop/objects", + "text": "Java Objects" + }, + { + "source": "/cs61b/abstract-data-types/collections/arrays", + "target": "/../../asymptotics/amortization", + "text": "Amortization" + }, + { + "source": "/cs61b/abstract-data-types/collections/arrays", + "target": "/../../oop/generics", + "text": "Generic Types" + }, + { + "source": "/cs61b/abstract-data-types/collections/arrays", + "target": "/./", + "text": "Collections" + }, + { + "source": "/cs61b/abstract-data-types/collections/linked-lists", + "target": "/arrays", + "text": "Arrays" + }, + { + "source": "/cs61b/abstract-data-types/collections/sets", + "target": "/../../asymptotics/amortization", + "text": "resized" + }, + { + "source": "/cs61b/abstract-data-types/collections/stacks-and-queues", + "target": "/../../algorithms/shortest-paths/dijkstras-algorithm", + "text": "finding shortest paths using Dijkstra's Algorithm" + }, + { + "source": "/cs61b/abstract-data-types/collections/stacks-and-queues", + "target": "/stacks-and-queues", + "text": "Priority Queues" + }, + { + "source": "/cs61b/abstract-data-types/graphs", + "target": "/../algorithms/searching/depth-first-search-dfs", + "text": "Depth First Search (DFS)" + }, + { + "source": "/cs61b/abstract-data-types/graphs", + "target": "/../algorithms/searching/breadth-first-search-bfs", + "text": "Breadth First Search (BFS)" + }, + { + "source": "/cs61b/abstract-data-types/graphs", + "target": "/../algorithms/minimum-spanning-trees/", + "text": "Minimum Spanning Trees" + }, + { + "source": "/cs61b/abstract-data-types/graphs", + "target": "/../algorithms/shortest-paths/", + "text": "Shortest Paths" + }, + { + "source": "/cs61b/abstract-data-types/graphs", + "target": "/../algorithms/shortest-paths/dijkstras-algorithm", + "text": "Dijkstra's Algorithm" + }, + { + "source": "/cs61b/abstract-data-types/graphs", + "target": "/../algorithms/shortest-paths/a-search", + "text": "A* Search" + }, + { + "source": "/cs61b/abstract-data-types/graphs", + "target": "/../algorithms/minimum-spanning-trees/prims-algorithm", + "text": "Prim's Algorithm" + }, + { + "source": "/cs61b/abstract-data-types/graphs", + "target": "/../algorithms/minimum-spanning-trees/kruskals-algorithm", + "text": "Kruskal's Algorithm" + }, + { + "source": "/cs61b/abstract-data-types/hashing", + "target": "/../asymptotics/amortization", + "text": "Amortization" + }, + { + "source": "/cs61b/abstract-data-types/union-find-disjoint-sets", + "target": "/../algorithms/minimum-spanning-trees/kruskals-algorithm", + "text": "Kruskal's Algorithm" + }, + { + "source": "/cs61b/algorithms/minimum-spanning-trees/kruskals-algorithm", + "target": "/./", + "text": "Minimum Spanning Trees" + }, + { + "source": "/cs61b/algorithms/minimum-spanning-trees/kruskals-algorithm", + "target": "/../../abstract-data-types/union-find-disjoint-sets", + "text": "Union Find (Disjoint Sets)" + }, + { + "source": "/cs61b/algorithms/minimum-spanning-trees/kruskals-algorithm", + "target": "/../../abstract-data-types/union-find-disjoint-sets", + "text": "Union Find (Disjoint Sets)" + }, + { + "source": "/cs61b/algorithms/minimum-spanning-trees/kruskals-algorithm", + "target": "/../../abstract-data-types/collections/stacks-and-queues", + "text": "PriorityQueue" + }, + { + "source": "/cs61b/algorithms/minimum-spanning-trees/prims-algorithm", + "target": "/./README", + "text": "Minimum Spanning Trees" + }, + { + "source": "/cs61b/algorithms/minimum-spanning-trees/prims-algorithm", + "target": "/../../abstract-data-types/collections/stacks-and-queues", + "text": "PriorityQueue" + }, + { + "source": "/cs61b/algorithms/minimum-spanning-trees/prims-algorithm", + "target": "/../shortest-paths/dijkstras-algorithm", + "text": "Dijkstra's" + }, + { + "source": "/cs61b/algorithms/searching/README", + "target": "/binary-search", + "text": "binary-search.md" + }, + { + "source": "/cs61b/algorithms/searching/README", + "target": "/depth-first-search-dfs", + "text": "depth-first-search-dfs.md" + }, + { + "source": "/cs61b/algorithms/searching/README", + "target": "/breadth-first-search-bfs", + "text": "breadth-first-search-bfs.md" + }, + { + "source": "/cs61b/algorithms/searching/binary-search", + "target": "/../../abstract-data-types/binary-trees/", + "text": "binary trees" + }, + { + "source": "/cs61b/algorithms/searching/breadth-first-search-bfs", + "target": "/depth-first-search-dfs", + "text": "Depth First Search (DFS)" + }, + { + "source": "/cs61b/algorithms/searching/breadth-first-search-bfs", + "target": "/../shortest-paths/dijkstras-algorithm", + "text": "Dijkstra's Algorithm" + }, + { + "source": "/cs61b/algorithms/shortest-paths/a-search", + "target": "/dijkstras-algorithm", + "text": "Dijkstra's Algorithm" + }, + { + "source": "/cs61b/algorithms/shortest-paths/dijkstras-algorithm", + "target": "/../../abstract-data-types/graphs", + "text": "Graphs" + }, + { + "source": "/cs61b/algorithms/shortest-paths/dijkstras-algorithm", + "target": "/../../abstract-data-types/collections/stacks-and-queues", + "text": "Stacks and Queues" + }, + { + "source": "/cs61b/algorithms/shortest-paths/dijkstras-algorithm", + "target": "/./", + "text": "Shortest Paths" + }, + { + "source": "/cs61b/asymptotics/amortization", + "target": "/asymptotics", + "text": "Asymptotic Analysis Basics" + }, + { + "source": "/cs61b/asymptotics/asymptotics-practice", + "target": "/asymptotics", + "text": "Asymptotic Analysis Basics" + }, + { + "source": "/cs61b/asymptotics/asymptotics", + "target": "/asymptotics-practice", + "text": "try some problems!" + }, + { + "source": "/cs61b/asymptotics/asymptotics", + "target": "/asymptotics", + "text": "Simplify" + }, + { + "source": "/cs61b/misc-topics/modular-arithmetic", + "target": "/../oop/objects", + "text": "Java Objects" + }, + { + "source": "/cs61b/oop/dynamic-method-selection", + "target": "/inheritance", + "text": "inheritance" + }, + { + "source": "/cs61b/oop/dynamic-method-selection", + "target": "/access-control", + "text": "access control" + }, + { + "source": "/cs61b/oop/dynamic-method-selection", + "target": "/inheritance", + "text": "Interfaces" + }, + { + "source": "/cs61b/oop/dynamic-method-selection", + "target": "/../abstract-data-types/collections/", + "text": "Collections" + }, + { + "source": "/cs61b/oop/generics", + "target": "/dynamic-method-selection", + "text": "Dynamic Method Selection" + }, + { + "source": "/cs61b/oop/generics", + "target": "/inheritance", + "text": "inheritance rules" + }, + { + "source": "/cs61b/oop/inheritance", + "target": "/access-control", + "text": "Access Control" + }, + { + "source": "/cs61b/oop/inheritance", + "target": "/objects", + "text": "References, Objects, and Types in Java" + }, + { + "source": "/cs61b/oop/inheritance", + "target": "/generics", + "text": "Generic Types" + }, + { + "source": "/cs61b/oop/inheritance", + "target": "/dynamic-method-selection", + "text": "Dynamic Method Selection" + }, + { + "source": "/cs61b/oop/objects", + "target": "/../misc-topics/modular-arithmetic", + "text": "Modular Arithmetic and Bit Manipulation" + }, + { + "source": "/cs61b/oop/objects", + "target": "/../abstract-data-types/collections/", + "text": "collections" + }, + { + "source": "/features/languages", + "target": "/notes/config", + "text": "config" } ] } \ No newline at end of file diff --git a/assets/quartz/styles/clipboard.scss b/assets/quartz/styles/clipboard.scss index 7989e24..34435a8 100644 --- a/assets/quartz/styles/clipboard.scss +++ b/assets/quartz/styles/clipboard.scss @@ -3,6 +3,7 @@ display: flex; float: right; right: 0; + top: 0; padding: 0.69em; margin: 0.5em; color: var(--outlinegray); diff --git a/config.yaml b/config.yaml index 2aa9864..34d051e 100644 --- a/config.yaml +++ b/config.yaml @@ -6,12 +6,12 @@ disablePathToLower: true enableGitInfo: true # # Needed for mermaid/katex shortcodes -# markup: -# goldmark: -# renderer: -# unsafe: true -# tableOfContents: -# startLevel: 1 +markup: + goldmark: + renderer: + unsafe: true + tableOfContents: + startLevel: 1 # Multi-lingual mode config # There are different options to translate files @@ -19,14 +19,14 @@ enableGitInfo: true # And https://gohugo.io/content-management/multilingual/#translation-by-content-directory menu: - # before: [] + # before: + # - name: "Sample" + # url: "https://google.com" + # weight: 10 after: - name: "Github" - url: "https://github.com/alex-shpak/hugo-book" + url: "https://github.com/64bitpandas/amethyst" weight: 10 - # - name: "Hugo Themes" - # url: "https://themes.gohugo.io/hugo-book/" - # weight: 20 params: diff --git a/content/.gitignore b/content/.gitignore new file mode 100644 index 0000000..f9523f9 --- /dev/null +++ b/content/.gitignore @@ -0,0 +1 @@ +cs61b \ No newline at end of file diff --git a/content/configuration/_index.md b/content/configuration/_index.md new file mode 100644 index 0000000..83d610f --- /dev/null +++ b/content/configuration/_index.md @@ -0,0 +1,4 @@ +--- +linkTitle: "Configuration" +weight: -5 +--- \ No newline at end of file diff --git a/content/notes/config.md b/content/configuration/config.md similarity index 100% rename from content/notes/config.md rename to content/configuration/config.md diff --git a/content/notes/custom Domain.md b/content/configuration/custom Domain.md similarity index 100% rename from content/notes/custom Domain.md rename to content/configuration/custom Domain.md diff --git a/content/notes/docker.md b/content/configuration/docker.md similarity index 100% rename from content/notes/docker.md rename to content/configuration/docker.md diff --git a/content/notes/editing.md b/content/configuration/editing.md similarity index 100% rename from content/notes/editing.md rename to content/configuration/editing.md diff --git a/content/notes/hosting.md b/content/configuration/hosting.md similarity index 100% rename from content/notes/hosting.md rename to content/configuration/hosting.md diff --git a/content/notes/ignore notes.md b/content/configuration/ignore notes.md similarity index 100% rename from content/notes/ignore notes.md rename to content/configuration/ignore notes.md diff --git a/content/notes/images/github-actions.png b/content/configuration/images/github-actions.png similarity index 100% rename from content/notes/images/github-actions.png rename to content/configuration/images/github-actions.png diff --git a/content/notes/images/github-pages.png b/content/configuration/images/github-pages.png similarity index 100% rename from content/notes/images/github-pages.png rename to content/configuration/images/github-pages.png diff --git a/content/notes/images/google-domains.png b/content/configuration/images/google-domains.png similarity index 100% rename from content/notes/images/google-domains.png rename to content/configuration/images/google-domains.png diff --git a/content/notes/images/obsidian-settings.png b/content/configuration/images/obsidian-settings.png similarity index 100% rename from content/notes/images/obsidian-settings.png rename to content/configuration/images/obsidian-settings.png diff --git a/content/notes/obsidian.md b/content/configuration/obsidian.md similarity index 100% rename from content/notes/obsidian.md rename to content/configuration/obsidian.md diff --git a/content/notes/preview changes.md b/content/configuration/preview changes.md similarity index 100% rename from content/notes/preview changes.md rename to content/configuration/preview changes.md diff --git a/content/notes/search.md b/content/configuration/search.md similarity index 100% rename from content/notes/search.md rename to content/configuration/search.md diff --git a/content/notes/setup.md b/content/configuration/setup.md similarity index 100% rename from content/notes/setup.md rename to content/configuration/setup.md diff --git a/content/notes/troubleshooting.md b/content/configuration/troubleshooting.md similarity index 100% rename from content/notes/troubleshooting.md rename to content/configuration/troubleshooting.md diff --git a/content/notes/updating.md b/content/configuration/updating.md similarity index 100% rename from content/notes/updating.md rename to content/configuration/updating.md diff --git a/content/docs/shortcodes/_index.md b/content/docs/shortcodes/_index.md deleted file mode 100644 index 9bb0430..0000000 --- a/content/docs/shortcodes/_index.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -bookFlatSection: true ---- diff --git a/content/docs/shortcodes/hints.md b/content/docs/shortcodes/hints.md deleted file mode 100644 index 3477113..0000000 --- a/content/docs/shortcodes/hints.md +++ /dev/null @@ -1,32 +0,0 @@ -# Hints - -Hint shortcode can be used as hint/alerts/notification block. -There are 3 colors to choose: `info`, `warning` and `danger`. - -```tpl -{{}} -**Markdown content** -Lorem markdownum insigne. Olympo signis Delphis! Retexi Nereius nova develat -stringit, frustra Saturnius uteroque inter! Oculis non ritibus Telethusa -{{}} -``` - -## Example - -{{< hint info >}} -**Markdown content** -Lorem markdownum insigne. Olympo signis Delphis! Retexi Nereius nova develat -stringit, frustra Saturnius uteroque inter! Oculis non ritibus Telethusa -{{< /hint >}} - -{{< hint warning >}} -**Markdown content** -Lorem markdownum insigne. Olympo signis Delphis! Retexi Nereius nova develat -stringit, frustra Saturnius uteroque inter! Oculis non ritibus Telethusa -{{< /hint >}} - -{{< hint danger >}} -**Markdown content** -Lorem markdownum insigne. Olympo signis Delphis! Retexi Nereius nova develat -stringit, frustra Saturnius uteroque inter! Oculis non ritibus Telethusa -{{< /hint >}} diff --git a/content/docs/shortcodes/katex.md b/content/docs/shortcodes/katex.md deleted file mode 100644 index 7587bd7..0000000 --- a/content/docs/shortcodes/katex.md +++ /dev/null @@ -1,28 +0,0 @@ -# KaTeX - -KaTeX shortcode let you render math typesetting in markdown document. See [KaTeX](https://katex.org/) - -## Example -{{< columns >}} - -```latex -{{}} -f(x) = \int_{-\infty}^\infty\hat f(\xi)\,e^{2 \pi i \xi x}\,d\xi -{{}} -``` - -<---> - -{{< katex display >}} -f(x) = \int_{-\infty}^\infty\hat f(\xi)\,e^{2 \pi i \xi x}\,d\xi -{{< /katex >}} - -{{< /columns >}} - -## Display Mode Example - -Here is some inline example: {{< katex >}}\pi(x){{< /katex >}}, rendered in the same line. And below is `display` example, having `display: block` -{{< katex display >}} -f(x) = \int_{-\infty}^\infty\hat f(\xi)\,e^{2 \pi i \xi x}\,d\xi -{{< /katex >}} -Text continues here. diff --git a/content/docs/example/_index.md b/content/example/_index.md similarity index 99% rename from content/docs/example/_index.md rename to content/example/_index.md index 4835b7c..973a085 100644 --- a/content/docs/example/_index.md +++ b/content/example/_index.md @@ -1,6 +1,6 @@ --- weight: 1 -bookFlatSection: true +bookCollapseSection: true title: "Example Site" --- diff --git a/content/docs/example/collapsed/3rd-level/4th-level.md b/content/example/collapsed/3rd-level/4th-level.md similarity index 100% rename from content/docs/example/collapsed/3rd-level/4th-level.md rename to content/example/collapsed/3rd-level/4th-level.md diff --git a/content/docs/example/collapsed/3rd-level/_index.md b/content/example/collapsed/3rd-level/_index.md similarity index 99% rename from content/docs/example/collapsed/3rd-level/_index.md rename to content/example/collapsed/3rd-level/_index.md index cc0100f..38fc580 100644 --- a/content/docs/example/collapsed/3rd-level/_index.md +++ b/content/example/collapsed/3rd-level/_index.md @@ -5,6 +5,7 @@ miror esse, scelerisque Melaneus viribus. Miseri laurus. Hoc est proposita me ante aliquid, aura inponere candidioribus quidque accendit bella, sumpta. Intravit quam erat figentem hunc, motus de fontes parvo tempestate. +```c iscsi_virus = pitch(json_in_on(eupViral), northbridge_services_troubleshooting, personal( firmware_rw.trash_rw_crm.device(interactive_gopher_personal, @@ -24,3 +25,4 @@ Intravit quam erat figentem hunc, motus de fontes parvo tempestate. coreLog.joystick(componentUdpLink), windows_expansion_touchscreen); bashGigabit.external.reality(2, server_hardware_codec.flops.ebookSampling( ciscNavigationBacklink, table + cleanDriver), indexProtocolIsp); +``` \ No newline at end of file diff --git a/content/docs/example/collapsed/_index.md b/content/example/collapsed/_index.md similarity index 78% rename from content/docs/example/collapsed/_index.md rename to content/example/collapsed/_index.md index e954f08..2898e65 100644 --- a/content/docs/example/collapsed/_index.md +++ b/content/example/collapsed/_index.md @@ -2,3 +2,5 @@ bookCollapseSection: true weight: 20 --- + +Hello World \ No newline at end of file diff --git a/content/docs/example/hidden.md b/content/example/hidden.md similarity index 100% rename from content/docs/example/hidden.md rename to content/example/hidden.md diff --git a/content/docs/example/table-of-contents/_index.md b/content/example/table-of-contents/_index.md similarity index 100% rename from content/docs/example/table-of-contents/_index.md rename to content/example/table-of-contents/_index.md diff --git a/content/docs/example/table-of-contents/with-toc.md b/content/example/table-of-contents/with-toc.md similarity index 100% rename from content/docs/example/table-of-contents/with-toc.md rename to content/example/table-of-contents/with-toc.md diff --git a/content/docs/example/table-of-contents/without-toc.md b/content/example/table-of-contents/without-toc.md similarity index 100% rename from content/docs/example/table-of-contents/without-toc.md rename to content/example/table-of-contents/without-toc.md diff --git a/content/features/_index.md b/content/features/_index.md new file mode 100644 index 0000000..37539b8 --- /dev/null +++ b/content/features/_index.md @@ -0,0 +1,3 @@ +--- +bookFlatSection: false +--- diff --git a/content/docs/shortcodes/buttons.md b/content/features/buttons.md similarity index 100% rename from content/docs/shortcodes/buttons.md rename to content/features/buttons.md diff --git a/content/notes/callouts.md b/content/features/callouts.md similarity index 100% rename from content/notes/callouts.md rename to content/features/callouts.md diff --git a/content/docs/shortcodes/columns.md b/content/features/columns.md similarity index 100% rename from content/docs/shortcodes/columns.md rename to content/features/columns.md diff --git a/content/docs/shortcodes/details.md b/content/features/details.md similarity index 100% rename from content/docs/shortcodes/details.md rename to content/features/details.md diff --git a/content/docs/shortcodes/expand.md b/content/features/expand.md similarity index 100% rename from content/docs/shortcodes/expand.md rename to content/features/expand.md diff --git a/content/features/languages.md b/content/features/languages.md new file mode 100644 index 0000000..46215d7 --- /dev/null +++ b/content/features/languages.md @@ -0,0 +1,13 @@ +--- +title: "Chinese, Japanese, Korean Support (测试)" +--- + +## Chinese, Japanese, Korean Support +几乎在我们意识到之前,我们已经离开了地面。 + +우리가 그것을 알기도 전에 우리는 땅을 떠났습니다. + +私たちがそれを知るほぼ前に、私たちは地面を離れていました。 + +## RTL +More information on configuring RTL languages like Arabic in the [config](notes/config.md) page. diff --git a/content/notes/CJK + Latex Support (测试).md b/content/features/latex.md similarity index 50% rename from content/notes/CJK + Latex Support (测试).md rename to content/features/latex.md index 0f9afc2..3de3662 100644 --- a/content/notes/CJK + Latex Support (测试).md +++ b/content/features/latex.md @@ -1,16 +1,7 @@ --- -title: "CJK + Latex Support (测试)" +title: "LaTeX" --- -## Chinese, Japanese, Korean Support -几乎在我们意识到之前,我们已经离开了地面。 - -우리가 그것을 알기도 전에 우리는 땅을 떠났습니다. - -私たちがそれを知るほぼ前に、私たちは地面を離れていました。 - -## Latex - Block math works with two dollar signs `$$...$$` $$f(x) = \int_{-\infty}^\infty @@ -34,7 +25,4 @@ $$ 1 & 2 & 3 \\ a & b & c \end{bmatrix} -$$ - -## RTL -More information on configuring RTL languages like Arabic in the [config](notes/config.md) page. +$$ \ No newline at end of file diff --git a/content/docs/shortcodes/mermaid.md b/content/features/mermaid.md similarity index 100% rename from content/docs/shortcodes/mermaid.md rename to content/features/mermaid.md diff --git a/content/docs/shortcodes/section/_index.md b/content/features/section/_index.md similarity index 100% rename from content/docs/shortcodes/section/_index.md rename to content/features/section/_index.md diff --git a/content/docs/shortcodes/section/first-page.md b/content/features/section/first-page.md similarity index 100% rename from content/docs/shortcodes/section/first-page.md rename to content/features/section/first-page.md diff --git a/content/docs/shortcodes/section/second-page.md b/content/features/section/second-page.md similarity index 100% rename from content/docs/shortcodes/section/second-page.md rename to content/features/section/second-page.md diff --git a/content/docs/shortcodes/tabs.md b/content/features/tabs.md similarity index 100% rename from content/docs/shortcodes/tabs.md rename to content/features/tabs.md diff --git a/content/menu/index.md b/content/menu/index.md deleted file mode 100644 index 45e8287..0000000 --- a/content/menu/index.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -headless: true ---- - -- [**Example Site**]({{< relref "/docs/example" >}}) -- [Table of Contents]({{< relref "/docs/example/table-of-contents" >}}) - - [With ToC]({{< relref "/docs/example/table-of-contents/with-toc" >}}) - - [Without ToC]({{< relref "/docs/example/table-of-contents/without-toc" >}}) -- [Collapsed]({{< relref "/docs/example/collapsed" >}}) - - [3rd]({{< relref "/docs/example/collapsed/3rd-level" >}}) - - [4th]({{< relref "/docs/example/collapsed/3rd-level/4th-level" >}}) -
- -- **Shortcodes** -- [Buttons]({{< relref "/docs/shortcodes/buttons" >}}) -- [Columns]({{< relref "/docs/shortcodes/columns" >}}) -- [Expand]({{< relref "/docs/shortcodes/expand" >}}) -- [Hints]({{< relref "/docs/shortcodes/hints" >}}) -- [KaTex]({{< relref "/docs/shortcodes/katex" >}}) -- [Mermaid]({{< relref "/docs/shortcodes/mermaid" >}}) -- [Tabs]({{< relref "/docs/shortcodes/tabs" >}}) -
diff --git a/content/notes/_index.md b/content/notes/_index.md deleted file mode 100644 index 44ede41..0000000 --- a/content/notes/_index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: "Test Notes" -bookCollapseSection: true ---- - -# Hello World \ No newline at end of file diff --git a/content/notes/philosophy.md b/content/notes/philosophy.md deleted file mode 100644 index bf04da3..0000000 --- a/content/notes/philosophy.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: "Quartz Philosophy" ---- - -> “[One] who works with the door open gets all kinds of interruptions, but [they] also occasionally gets clues as to what the world is and what might be important.” — Richard Hamming - -## Why Quartz? -Hosting a public digital garden isn't easy. There are an overwhelming number of tutorials, resources, and guides for tools like [Notion](https://www.notion.so/), [Roam](https://roamresearch.com/), and [Obsidian](https://obsidian.md/), yet none of them have super easy to use *free* tools to publish that garden to the world. - -I've personally found that -1. It's nice to access notes from anywhere -2. Having a public digital garden invites open conversations -3. It makes keeping personal notes and knowledge *playful and fun* - -I was really inspired by [Bianca](https://garden.bianca.digital/) and [Joel](https://joelhooks.com/digital-garden)'s digital gardens and wanted to try making my own. - -**The goal of Quartz is to make hosting your own public digital garden free and simple.** You don't even need your own website. Quartz does all of that for you and gives your own little corner of the internet. diff --git a/content/notes/showcase.md b/content/notes/showcase.md deleted file mode 100644 index cfa81d9..0000000 --- a/content/notes/showcase.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: "Showcase" ---- - -Want to see what Quartz can do? Here are some cool community gardens :) - -- [Quartz Documentation (this site!)](https://quartz.jzhao.xyz/) -- [Jacky Zhao's Garden](https://jzhao.xyz/) -- [Scaling Synthesis - A hypertext research notebook](https://scalingsynthesis.com/) -- [AWAGMI Intern Notes](https://notes.awagmi.xyz/) -- [Shihyu's PKM](https://shihyuho.github.io/pkm/) -- [Chloe's Garden](https://garden.chloeabrasada.online/) -- [SlRvb's Site](https://slrvb.github.io/Site/) -- [Course notes for Information Technology Advanced Theory](https://a2itnotes.github.io/quartz/) -- [Brandon Boswell's Garden](https://brandonkboswell.com) -- [Siyang's Courtyard](https://siyangsun.github.io/courtyard/) -- [Data Dictionary 🧠](https://glossary.airbyte.com/) -- [sspaeti.com's Second Brain](https://brain.sspaeti.com/) -- [oldwinterの数字花园](https://garden.oldwinter.top/) -- [SethMB Work](https://sethmb.xyz/) -- [Abhijeet's Math Wiki](https://abhmul.github.io/quartz/Math-Wiki/) - -If you want to see your own on here, submit a [Pull Request adding yourself to this file](https://github.com/jackyzha0/quartz/blob/hugo/content/notes/showcase.md)! diff --git a/content/posts/_index.md b/content/posts/_index.md deleted file mode 100644 index 001ae24..0000000 --- a/content/posts/_index.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -menu: - after: - name: blog - weight: 5 -title: Blog ---- diff --git a/content/posts/creating-a-new-theme.md b/content/posts/creating-a-new-theme.md deleted file mode 100644 index f8230a1..0000000 --- a/content/posts/creating-a-new-theme.md +++ /dev/null @@ -1,1150 +0,0 @@ ---- -author: "Michael Henderson" -date: 2014-09-28 -linktitle: Creating a New Theme -menu: - main: - parent: tutorials -next: /tutorials/github-pages-blog -prev: /tutorials/automated-deployments -title: Creating a New Theme -weight: 10 ---- - - -## Introduction - -This tutorial will show you how to create a simple theme in Hugo. I assume that you are familiar with HTML, the bash command line, and that you are comfortable using Markdown to format content. I'll explain how Hugo uses templates and how you can organize your templates to create a theme. I won't cover using CSS to style your theme. - -We'll start with creating a new site with a very basic template. Then we'll add in a few pages and posts. With small variations on that, you will be able to create many different types of web sites. - -In this tutorial, commands that you enter will start with the "$" prompt. The output will follow. Lines that start with "#" are comments that I've added to explain a point. When I show updates to a file, the ":wq" on the last line means to save the file. - -Here's an example: - -``` -## this is a comment -$ echo this is a command -this is a command - -## edit the file -$ vi foo.md -+++ -date = "2014-09-28" -title = "creating a new theme" -+++ - -bah and humbug -:wq - -## show it -$ cat foo.md -+++ -date = "2014-09-28" -title = "creating a new theme" -+++ - -bah and humbug -$ -``` - - -## Some Definitions - -There are a few concepts that you need to understand before creating a theme. - -### Skins - -Skins are the files responsible for the look and feel of your site. It’s the CSS that controls colors and fonts, it’s the Javascript that determines actions and reactions. It’s also the rules that Hugo uses to transform your content into the HTML that the site will serve to visitors. - -You have two ways to create a skin. The simplest way is to create it in the ```layouts/``` directory. If you do, then you don’t have to worry about configuring Hugo to recognize it. The first place that Hugo will look for rules and files is in the ```layouts/``` directory so it will always find the skin. - -Your second choice is to create it in a sub-directory of the ```themes/``` directory. If you do, then you must always tell Hugo where to search for the skin. It’s extra work, though, so why bother with it? - -The difference between creating a skin in ```layouts/``` and creating it in ```themes/``` is very subtle. A skin in ```layouts/``` can’t be customized without updating the templates and static files that it is built from. A skin created in ```themes/```, on the other hand, can be and that makes it easier for other people to use it. - -The rest of this tutorial will call a skin created in the ```themes/``` directory a theme. - -Note that you can use this tutorial to create a skin in the ```layouts/``` directory if you wish to. The main difference will be that you won’t need to update the site’s configuration file to use a theme. - -### The Home Page - -The home page, or landing page, is the first page that many visitors to a site see. It is the index.html file in the root directory of the web site. Since Hugo writes files to the public/ directory, our home page is public/index.html. - -### Site Configuration File - -When Hugo runs, it looks for a configuration file that contains settings that override default values for the entire site. The file can use TOML, YAML, or JSON. I prefer to use TOML for my configuration files. If you prefer to use JSON or YAML, you’ll need to translate my examples. You’ll also need to change the name of the file since Hugo uses the extension to determine how to process it. - -Hugo translates Markdown files into HTML. By default, Hugo expects to find Markdown files in your ```content/``` directory and template files in your ```themes/``` directory. It will create HTML files in your ```public/``` directory. You can change this by specifying alternate locations in the configuration file. - -### Content - -Content is stored in text files that contain two sections. The first section is the “front matter,” which is the meta-information on the content. The second section contains Markdown that will be converted to HTML. - -#### Front Matter - -The front matter is information about the content. Like the configuration file, it can be written in TOML, YAML, or JSON. Unlike the configuration file, Hugo doesn’t use the file’s extension to know the format. It looks for markers to signal the type. TOML is surrounded by “`+++`”, YAML by “`---`”, and JSON is enclosed in curly braces. I prefer to use TOML, so you’ll need to translate my examples if you prefer YAML or JSON. - -The information in the front matter is passed into the template before the content is rendered into HTML. - -#### Markdown - -Content is written in Markdown which makes it easier to create the content. Hugo runs the content through a Markdown engine to create the HTML which will be written to the output file. - -### Template Files - -Hugo uses template files to render content into HTML. Template files are a bridge between the content and presentation. Rules in the template define what content is published, where it's published to, and how it will rendered to the HTML file. The template guides the presentation by specifying the style to use. - -There are three types of templates: single, list, and partial. Each type takes a bit of content as input and transforms it based on the commands in the template. - -Hugo uses its knowledge of the content to find the template file used to render the content. If it can’t find a template that is an exact match for the content, it will shift up a level and search from there. It will continue to do so until it finds a matching template or runs out of templates to try. If it can’t find a template, it will use the default template for the site. - -Please note that you can use the front matter to influence Hugo’s choice of templates. - -#### Single Template - -A single template is used to render a single piece of content. For example, an article or post would be a single piece of content and use a single template. - -#### List Template - -A list template renders a group of related content. That could be a summary of recent postings or all articles in a category. List templates can contain multiple groups. - -The homepage template is a special type of list template. Hugo assumes that the home page of your site will act as the portal for the rest of the content in the site. - -#### Partial Template - -A partial template is a template that can be included in other templates. Partial templates must be called using the “partial” template command. They are very handy for rolling up common behavior. For example, your site may have a banner that all pages use. Instead of copying the text of the banner into every single and list template, you could create a partial with the banner in it. That way if you decide to change the banner, you only have to change the partial template. - -## Create a New Site - -Let's use Hugo to create a new web site. I'm a Mac user, so I'll create mine in my home directory, in the Sites folder. If you're using Linux, you might have to create the folder first. - -The "new site" command will create a skeleton of a site. It will give you the basic directory structure and a useable configuration file. - -``` -$ hugo new site ~/Sites/zafta -$ cd ~/Sites/zafta -$ ls -l -total 8 -drwxr-xr-x 7 quoha staff 238 Sep 29 16:49 . -drwxr-xr-x 3 quoha staff 102 Sep 29 16:49 .. -drwxr-xr-x 2 quoha staff 68 Sep 29 16:49 archetypes --rw-r--r-- 1 quoha staff 82 Sep 29 16:49 config.toml -drwxr-xr-x 2 quoha staff 68 Sep 29 16:49 content -drwxr-xr-x 2 quoha staff 68 Sep 29 16:49 layouts -drwxr-xr-x 2 quoha staff 68 Sep 29 16:49 static -$ -``` - -Take a look in the content/ directory to confirm that it is empty. - -The other directories (archetypes/, layouts/, and static/) are used when customizing a theme. That's a topic for a different tutorial, so please ignore them for now. - -### Generate the HTML For the New Site - -Running the `hugo` command with no options will read all the available content and generate the HTML files. It will also copy all static files (that's everything that's not content). Since we have an empty site, it won't do much, but it will do it very quickly. - -``` -$ hugo --verbose -INFO: 2014/09/29 Using config file: config.toml -INFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/static/ to /Users/quoha/Sites/zafta/public/ -WARN: 2014/09/29 Unable to locate layout: [index.html _default/list.html _default/single.html] -WARN: 2014/09/29 Unable to locate layout: [404.html] -0 draft content -0 future content -0 pages created -0 tags created -0 categories created -in 2 ms -$ -``` - -The "`--verbose`" flag gives extra information that will be helpful when we build the template. Every line of the output that starts with "INFO:" or "WARN:" is present because we used that flag. The lines that start with "WARN:" are warning messages. We'll go over them later. - -We can verify that the command worked by looking at the directory again. - -``` -$ ls -l -total 8 -drwxr-xr-x 2 quoha staff 68 Sep 29 16:49 archetypes --rw-r--r-- 1 quoha staff 82 Sep 29 16:49 config.toml -drwxr-xr-x 2 quoha staff 68 Sep 29 16:49 content -drwxr-xr-x 2 quoha staff 68 Sep 29 16:49 layouts -drwxr-xr-x 4 quoha staff 136 Sep 29 17:02 public -drwxr-xr-x 2 quoha staff 68 Sep 29 16:49 static -$ -``` - -See that new public/ directory? Hugo placed all generated content there. When you're ready to publish your web site, that's the place to start. For now, though, let's just confirm that we have what we'd expect from a site with no content. - -``` -$ ls -l public -total 16 --rw-r--r-- 1 quoha staff 416 Sep 29 17:02 index.xml --rw-r--r-- 1 quoha staff 262 Sep 29 17:02 sitemap.xml -$ -``` - -Hugo created two XML files, which is standard, but there are no HTML files. - - - -### Test the New Site - -Verify that you can run the built-in web server. It will dramatically shorten your development cycle if you do. Start it by running the "server" command. If it is successful, you will see output similar to the following: - -``` -$ hugo server --verbose -INFO: 2014/09/29 Using config file: /Users/quoha/Sites/zafta/config.toml -INFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/static/ to /Users/quoha/Sites/zafta/public/ -WARN: 2014/09/29 Unable to locate layout: [index.html _default/list.html _default/single.html] -WARN: 2014/09/29 Unable to locate layout: [404.html] -0 draft content -0 future content -0 pages created -0 tags created -0 categories created -in 2 ms -Serving pages from /Users/quoha/Sites/zafta/public -Web Server is available at http://localhost:1313 -Press Ctrl+C to stop -``` - -Connect to the listed URL (it's on the line that starts with "Web Server"). If everything is working correctly, you should get a page that shows the following: - -``` -index.xml -sitemap.xml -``` - -That's a listing of your public/ directory. Hugo didn't create a home page because our site has no content. When there's no index.html file in a directory, the server lists the files in the directory, which is what you should see in your browser. - -Let’s go back and look at those warnings again. - -``` -WARN: 2014/09/29 Unable to locate layout: [index.html _default/list.html _default/single.html] -WARN: 2014/09/29 Unable to locate layout: [404.html] -``` - -That second warning is easier to explain. We haven’t created a template to be used to generate “page not found errors.” The 404 message is a topic for a separate tutorial. - -Now for the first warning. It is for the home page. You can tell because the first layout that it looked for was “index.html.” That’s only used by the home page. - -I like that the verbose flag causes Hugo to list the files that it's searching for. For the home page, they are index.html, _default/list.html, and _default/single.html. There are some rules that we'll cover later that explain the names and paths. For now, just remember that Hugo couldn't find a template for the home page and it told you so. - -At this point, you've got a working installation and site that we can build upon. All that’s left is to add some content and a theme to display it. - -## Create a New Theme - -Hugo doesn't ship with a default theme. There are a few available (I counted a dozen when I first installed Hugo) and Hugo comes with a command to create new themes. - -We're going to create a new theme called "zafta." Since the goal of this tutorial is to show you how to fill out the files to pull in your content, the theme will not contain any CSS. In other words, ugly but functional. - -All themes have opinions on content and layout. For example, Zafta uses "post" over "blog". Strong opinions make for simpler templates but differing opinions make it tougher to use themes. When you build a theme, consider using the terms that other themes do. - - -### Create a Skeleton - -Use the hugo "new" command to create the skeleton of a theme. This creates the directory structure and places empty files for you to fill out. - -``` -$ hugo new theme zafta - -$ ls -l -total 8 -drwxr-xr-x 2 quoha staff 68 Sep 29 16:49 archetypes --rw-r--r-- 1 quoha staff 82 Sep 29 16:49 config.toml -drwxr-xr-x 2 quoha staff 68 Sep 29 16:49 content -drwxr-xr-x 2 quoha staff 68 Sep 29 16:49 layouts -drwxr-xr-x 4 quoha staff 136 Sep 29 17:02 public -drwxr-xr-x 2 quoha staff 68 Sep 29 16:49 static -drwxr-xr-x 3 quoha staff 102 Sep 29 17:31 themes - -$ find themes -type f | xargs ls -l --rw-r--r-- 1 quoha staff 1081 Sep 29 17:31 themes/zafta/LICENSE.md --rw-r--r-- 1 quoha staff 0 Sep 29 17:31 themes/zafta/archetypes/default.md --rw-r--r-- 1 quoha staff 0 Sep 29 17:31 themes/zafta/layouts/_default/list.html --rw-r--r-- 1 quoha staff 0 Sep 29 17:31 themes/zafta/layouts/_default/single.html --rw-r--r-- 1 quoha staff 0 Sep 29 17:31 themes/zafta/layouts/index.html --rw-r--r-- 1 quoha staff 0 Sep 29 17:31 themes/zafta/layouts/partials/footer.html --rw-r--r-- 1 quoha staff 0 Sep 29 17:31 themes/zafta/layouts/partials/header.html --rw-r--r-- 1 quoha staff 93 Sep 29 17:31 themes/zafta/theme.toml -$ -``` - -The skeleton includes templates (the files ending in .html), license file, a description of your theme (the theme.toml file), and an empty archetype. - -Please take a minute to fill out the theme.toml and LICENSE.md files. They're optional, but if you're going to be distributing your theme, it tells the world who to praise (or blame). It's also nice to declare the license so that people will know how they can use the theme. - -``` -$ vi themes/zafta/theme.toml -author = "michael d henderson" -description = "a minimal working template" -license = "MIT" -name = "zafta" -source_repo = "" -tags = ["tags", "categories"] -:wq - -## also edit themes/zafta/LICENSE.md and change -## the bit that says "YOUR_NAME_HERE" -``` - -Note that the the skeleton's template files are empty. Don't worry, we'll be changing that shortly. - -``` -$ find themes/zafta -name '*.html' | xargs ls -l --rw-r--r-- 1 quoha staff 0 Sep 29 17:31 themes/zafta/layouts/_default/list.html --rw-r--r-- 1 quoha staff 0 Sep 29 17:31 themes/zafta/layouts/_default/single.html --rw-r--r-- 1 quoha staff 0 Sep 29 17:31 themes/zafta/layouts/index.html --rw-r--r-- 1 quoha staff 0 Sep 29 17:31 themes/zafta/layouts/partials/footer.html --rw-r--r-- 1 quoha staff 0 Sep 29 17:31 themes/zafta/layouts/partials/header.html -$ -``` - - - -### Update the Configuration File to Use the Theme - -Now that we've got a theme to work with, it's a good idea to add the theme name to the configuration file. This is optional, because you can always add "-t zafta" on all your commands. I like to put it the configuration file because I like shorter command lines. If you don't put it in the configuration file or specify it on the command line, you won't use the template that you're expecting to. - -Edit the file to add the theme, add a title for the site, and specify that all of our content will use the TOML format. - -``` -$ vi config.toml -theme = "zafta" -baseurl = "" -languageCode = "en-us" -title = "zafta - totally refreshing" -MetaDataFormat = "toml" -:wq - -$ -``` - -### Generate the Site - -Now that we have an empty theme, let's generate the site again. - -``` -$ hugo --verbose -INFO: 2014/09/29 Using config file: /Users/quoha/Sites/zafta/config.toml -INFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/themes/zafta/static/ to /Users/quoha/Sites/zafta/public/ -INFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/static/ to /Users/quoha/Sites/zafta/public/ -WARN: 2014/09/29 Unable to locate layout: [404.html theme/404.html] -0 draft content -0 future content -0 pages created -0 tags created -0 categories created -in 2 ms -$ -``` - -Did you notice that the output is different? The warning message for the home page has disappeared and we have an additional information line saying that Hugo is syncing from the theme's directory. - -Let's check the public/ directory to see what Hugo's created. - -``` -$ ls -l public -total 16 -drwxr-xr-x 2 quoha staff 68 Sep 29 17:56 css --rw-r--r-- 1 quoha staff 0 Sep 29 17:56 index.html --rw-r--r-- 1 quoha staff 407 Sep 29 17:56 index.xml -drwxr-xr-x 2 quoha staff 68 Sep 29 17:56 js --rw-r--r-- 1 quoha staff 243 Sep 29 17:56 sitemap.xml -$ -``` - -Notice four things: - -1. Hugo created a home page. This is the file public/index.html. -2. Hugo created a css/ directory. -3. Hugo created a js/ directory. -4. Hugo claimed that it created 0 pages. It created a file and copied over static files, but didn't create any pages. That's because it considers a "page" to be a file created directly from a content file. It doesn't count things like the index.html files that it creates automatically. - -#### The Home Page - -Hugo supports many different types of templates. The home page is special because it gets its own type of template and its own template file. The file, layouts/index.html, is used to generate the HTML for the home page. The Hugo documentation says that this is the only required template, but that depends. Hugo's warning message shows that it looks for three different templates: - -``` -WARN: 2014/09/29 Unable to locate layout: [index.html _default/list.html _default/single.html] -``` - -If it can't find any of these, it completely skips creating the home page. We noticed that when we built the site without having a theme installed. - -When Hugo created our theme, it created an empty home page template. Now, when we build the site, Hugo finds the template and uses it to generate the HTML for the home page. Since the template file is empty, the HTML file is empty, too. If the template had any rules in it, then Hugo would have used them to generate the home page. - -``` -$ find . -name index.html | xargs ls -l --rw-r--r-- 1 quoha staff 0 Sep 29 20:21 ./public/index.html --rw-r--r-- 1 quoha staff 0 Sep 29 17:31 ./themes/zafta/layouts/index.html -$ -``` - -#### The Magic of Static - -Hugo does two things when generating the site. It uses templates to transform content into HTML and it copies static files into the site. Unlike content, static files are not transformed. They are copied exactly as they are. - -Hugo assumes that your site will use both CSS and JavaScript, so it creates directories in your theme to hold them. Remember opinions? Well, Hugo's opinion is that you'll store your CSS in a directory named css/ and your JavaScript in a directory named js/. If you don't like that, you can change the directory names in your theme directory or even delete them completely. Hugo's nice enough to offer its opinion, then behave nicely if you disagree. - -``` -$ find themes/zafta -type d | xargs ls -ld -drwxr-xr-x 7 quoha staff 238 Sep 29 17:38 themes/zafta -drwxr-xr-x 3 quoha staff 102 Sep 29 17:31 themes/zafta/archetypes -drwxr-xr-x 5 quoha staff 170 Sep 29 17:31 themes/zafta/layouts -drwxr-xr-x 4 quoha staff 136 Sep 29 17:31 themes/zafta/layouts/_default -drwxr-xr-x 4 quoha staff 136 Sep 29 17:31 themes/zafta/layouts/partials -drwxr-xr-x 4 quoha staff 136 Sep 29 17:31 themes/zafta/static -drwxr-xr-x 2 quoha staff 68 Sep 29 17:31 themes/zafta/static/css -drwxr-xr-x 2 quoha staff 68 Sep 29 17:31 themes/zafta/static/js -$ -``` - -## The Theme Development Cycle - -When you're working on a theme, you will make changes in the theme's directory, rebuild the site, and check your changes in the browser. Hugo makes this very easy: - -1. Purge the public/ directory. -2. Run the built in web server in watch mode. -3. Open your site in a browser. -4. Update the theme. -5. Glance at your browser window to see changes. -6. Return to step 4. - -I’ll throw in one more opinion: never work on a theme on a live site. Always work on a copy of your site. Make changes to your theme, test them, then copy them up to your site. For added safety, use a tool like Git to keep a revision history of your content and your theme. Believe me when I say that it is too easy to lose both your mind and your changes. - -Check the main Hugo site for information on using Git with Hugo. - -### Purge the public/ Directory - -When generating the site, Hugo will create new files and update existing ones in the ```public/``` directory. It will not delete files that are no longer used. For example, files that were created in the wrong directory or with the wrong title will remain. If you leave them, you might get confused by them later. I recommend cleaning out your site prior to generating it. - -Note: If you're building on an SSD, you should ignore this. Churning on a SSD can be costly. - -### Hugo's Watch Option - -Hugo's "`--watch`" option will monitor the content/ and your theme directories for changes and rebuild the site automatically. - -### Live Reload - -Hugo's built in web server supports live reload. As pages are saved on the server, the browser is told to refresh the page. Usually, this happens faster than you can say, "Wow, that's totally amazing." - -### Development Commands - -Use the following commands as the basis for your workflow. - -``` -## purge old files. hugo will recreate the public directory. -## -$ rm -rf public -## -## run hugo in watch mode -## -$ hugo server --watch --verbose -``` - -Here's sample output showing Hugo detecting a change to the template for the home page. Once generated, the web browser automatically reloaded the page. I've said this before, it's amazing. - - -``` -$ rm -rf public -$ hugo server --watch --verbose -INFO: 2014/09/29 Using config file: /Users/quoha/Sites/zafta/config.toml -INFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/themes/zafta/static/ to /Users/quoha/Sites/zafta/public/ -INFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/static/ to /Users/quoha/Sites/zafta/public/ -WARN: 2014/09/29 Unable to locate layout: [404.html theme/404.html] -0 draft content -0 future content -0 pages created -0 tags created -0 categories created -in 2 ms -Watching for changes in /Users/quoha/Sites/zafta/content -Serving pages from /Users/quoha/Sites/zafta/public -Web Server is available at http://localhost:1313 -Press Ctrl+C to stop -INFO: 2014/09/29 File System Event: ["/Users/quoha/Sites/zafta/themes/zafta/layouts/index.html": MODIFY|ATTRIB] -Change detected, rebuilding site - -WARN: 2014/09/29 Unable to locate layout: [404.html theme/404.html] -0 draft content -0 future content -0 pages created -0 tags created -0 categories created -in 1 ms -``` - -## Update the Home Page Template - -The home page is one of a few special pages that Hugo creates automatically. As mentioned earlier, it looks for one of three files in the theme's layout/ directory: - -1. index.html -2. _default/list.html -3. _default/single.html - -We could update one of the default templates, but a good design decision is to update the most specific template available. That's not a hard and fast rule (in fact, we'll break it a few times in this tutorial), but it is a good generalization. - -### Make a Static Home Page - -Right now, that page is empty because we don't have any content and we don't have any logic in the template. Let's change that by adding some text to the template. - -``` -$ vi themes/zafta/layouts/index.html - - - -

hugo says hello!

- - -:wq - -$ -``` - -Build the web site and then verify the results. - -``` -$ hugo --verbose -INFO: 2014/09/29 Using config file: /Users/quoha/Sites/zafta/config.toml -INFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/themes/zafta/static/ to /Users/quoha/Sites/zafta/public/ -INFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/static/ to /Users/quoha/Sites/zafta/public/ -WARN: 2014/09/29 Unable to locate layout: [404.html theme/404.html] -0 draft content -0 future content -0 pages created -0 tags created -0 categories created -in 2 ms - -$ find public -type f -name '*.html' | xargs ls -l --rw-r--r-- 1 quoha staff 78 Sep 29 21:26 public/index.html - -$ cat public/index.html - - - -

hugo says hello!

- -``` - -#### Live Reload - -Note: If you're running the server with the `--watch` option, you'll see different content in the file: - -``` -$ cat public/index.html - - - -

hugo says hello!

- - -``` - -When you use `--watch`, the Live Reload script is added by Hugo. Look for live reload in the documentation to see what it does and how to disable it. - -### Build a "Dynamic" Home Page - -"Dynamic home page?" Hugo's a static web site generator, so this seems an odd thing to say. I mean let's have the home page automatically reflect the content in the site every time Hugo builds it. We'll use iteration in the template to do that. - -#### Create New Posts - -Now that we have the home page generating static content, let's add some content to the site. We'll display these posts as a list on the home page and on their own page, too. - -Hugo has a command to generate a skeleton post, just like it does for sites and themes. - -``` -$ hugo --verbose new post/first.md -INFO: 2014/09/29 Using config file: /Users/quoha/Sites/zafta/config.toml -INFO: 2014/09/29 attempting to create post/first.md of post -INFO: 2014/09/29 curpath: /Users/quoha/Sites/zafta/themes/zafta/archetypes/default.md -ERROR: 2014/09/29 Unable to Cast to map[string]interface{} - -$ -``` - -That wasn't very nice, was it? - -The "new" command uses an archetype to create the post file. Hugo created an empty default archetype file, but that causes an error when there's a theme. For me, the workaround was to create an archetypes file specifically for the post type. - -``` -$ vi themes/zafta/archetypes/post.md -+++ -Description = "" -Tags = [] -Categories = [] -+++ -:wq - -$ find themes/zafta/archetypes -type f | xargs ls -l --rw-r--r-- 1 quoha staff 0 Sep 29 21:53 themes/zafta/archetypes/default.md --rw-r--r-- 1 quoha staff 51 Sep 29 21:54 themes/zafta/archetypes/post.md - -$ hugo --verbose new post/first.md -INFO: 2014/09/29 Using config file: /Users/quoha/Sites/zafta/config.toml -INFO: 2014/09/29 attempting to create post/first.md of post -INFO: 2014/09/29 curpath: /Users/quoha/Sites/zafta/themes/zafta/archetypes/post.md -INFO: 2014/09/29 creating /Users/quoha/Sites/zafta/content/post/first.md -/Users/quoha/Sites/zafta/content/post/first.md created - -$ hugo --verbose new post/second.md -INFO: 2014/09/29 Using config file: /Users/quoha/Sites/zafta/config.toml -INFO: 2014/09/29 attempting to create post/second.md of post -INFO: 2014/09/29 curpath: /Users/quoha/Sites/zafta/themes/zafta/archetypes/post.md -INFO: 2014/09/29 creating /Users/quoha/Sites/zafta/content/post/second.md -/Users/quoha/Sites/zafta/content/post/second.md created - -$ ls -l content/post -total 16 --rw-r--r-- 1 quoha staff 104 Sep 29 21:54 first.md --rw-r--r-- 1 quoha staff 105 Sep 29 21:57 second.md - -$ cat content/post/first.md -+++ -Categories = [] -Description = "" -Tags = [] -date = "2014-09-29T21:54:53-05:00" -title = "first" - -+++ -my first post - -$ cat content/post/second.md -+++ -Categories = [] -Description = "" -Tags = [] -date = "2014-09-29T21:57:09-05:00" -title = "second" - -+++ -my second post - -$ -``` - -Build the web site and then verify the results. - -``` -$ rm -rf public -$ hugo --verbose -INFO: 2014/09/29 Using config file: /Users/quoha/Sites/zafta/config.toml -INFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/themes/zafta/static/ to /Users/quoha/Sites/zafta/public/ -INFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/static/ to /Users/quoha/Sites/zafta/public/ -INFO: 2014/09/29 found taxonomies: map[string]string{"category":"categories", "tag":"tags"} -WARN: 2014/09/29 Unable to locate layout: [404.html theme/404.html] -0 draft content -0 future content -2 pages created -0 tags created -0 categories created -in 4 ms -$ -``` - -The output says that it created 2 pages. Those are our new posts: - -``` -$ find public -type f -name '*.html' | xargs ls -l --rw-r--r-- 1 quoha staff 78 Sep 29 22:13 public/index.html --rw-r--r-- 1 quoha staff 0 Sep 29 22:13 public/post/first/index.html --rw-r--r-- 1 quoha staff 0 Sep 29 22:13 public/post/index.html --rw-r--r-- 1 quoha staff 0 Sep 29 22:13 public/post/second/index.html -$ -``` - -The new files are empty because because the templates used to generate the content are empty. The homepage doesn't show the new content, either. We have to update the templates to add the posts. - -### List and Single Templates - -In Hugo, we have three major kinds of templates. There's the home page template that we updated previously. It is used only by the home page. We also have "single" templates which are used to generate output for a single content file. We also have "list" templates that are used to group multiple pieces of content before generating output. - -Generally speaking, list templates are named "list.html" and single templates are named "single.html." - -There are three other types of templates: partials, content views, and terms. We will not go into much detail on these. - -### Add Content to the Homepage - -The home page will contain a list of posts. Let's update its template to add the posts that we just created. The logic in the template will run every time we build the site. - -``` -$ vi themes/zafta/layouts/index.html - - - - {{ range first 10 .Data.Pages }} -

{{ .Title }}

- {{ end }} - - -:wq - -$ -``` - -Hugo uses the Go template engine. That engine scans the template files for commands which are enclosed between "{{" and "}}". In our template, the commands are: - -1. range -2. .Title -3. end - -The "range" command is an iterator. We're going to use it to go through the first ten pages. Every HTML file that Hugo creates is treated as a page, so looping through the list of pages will look at every file that will be created. - -The ".Title" command prints the value of the "title" variable. Hugo pulls it from the front matter in the Markdown file. - -The "end" command signals the end of the range iterator. The engine loops back to the top of the iteration when it finds "end." Everything between the "range" and "end" is evaluated every time the engine goes through the iteration. In this file, that would cause the title from the first ten pages to be output as heading level one. - -It's helpful to remember that some variables, like .Data, are created before any output files. Hugo loads every content file into the variable and then gives the template a chance to process before creating the HTML files. - -Build the web site and then verify the results. - -``` -$ rm -rf public -$ hugo --verbose -INFO: 2014/09/29 Using config file: /Users/quoha/Sites/zafta/config.toml -INFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/themes/zafta/static/ to /Users/quoha/Sites/zafta/public/ -INFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/static/ to /Users/quoha/Sites/zafta/public/ -INFO: 2014/09/29 found taxonomies: map[string]string{"tag":"tags", "category":"categories"} -WARN: 2014/09/29 Unable to locate layout: [404.html theme/404.html] -0 draft content -0 future content -2 pages created -0 tags created -0 categories created -in 4 ms -$ find public -type f -name '*.html' | xargs ls -l --rw-r--r-- 1 quoha staff 94 Sep 29 22:23 public/index.html --rw-r--r-- 1 quoha staff 0 Sep 29 22:23 public/post/first/index.html --rw-r--r-- 1 quoha staff 0 Sep 29 22:23 public/post/index.html --rw-r--r-- 1 quoha staff 0 Sep 29 22:23 public/post/second/index.html -$ cat public/index.html - - - - -

second

- -

first

- - - -$ -``` - -Congratulations, the home page shows the title of the two posts. The posts themselves are still empty, but let's take a moment to appreciate what we've done. Your template now generates output dynamically. Believe it or not, by inserting the range command inside of those curly braces, you've learned everything you need to know to build a theme. All that's really left is understanding which template will be used to generate each content file and becoming familiar with the commands for the template engine. - -And, if that were entirely true, this tutorial would be much shorter. There are a few things to know that will make creating a new template much easier. Don't worry, though, that's all to come. - -### Add Content to the Posts - -We're working with posts, which are in the content/post/ directory. That means that their section is "post" (and if we don't do something weird, their type is also "post"). - -Hugo uses the section and type to find the template file for every piece of content. Hugo will first look for a template file that matches the section or type name. If it can't find one, then it will look in the _default/ directory. There are some twists that we'll cover when we get to categories and tags, but for now we can assume that Hugo will try post/single.html, then _default/single.html. - -Now that we know the search rule, let's see what we actually have available: - -``` -$ find themes/zafta -name single.html | xargs ls -l --rw-r--r-- 1 quoha staff 132 Sep 29 17:31 themes/zafta/layouts/_default/single.html -``` - -We could create a new template, post/single.html, or change the default. Since we don't know of any other content types, let's start with updating the default. - -Remember, any content that we haven't created a template for will end up using this template. That can be good or bad. Bad because I know that we're going to be adding different types of content and we're going to end up undoing some of the changes we've made. It's good because we'll be able to see immediate results. It's also good to start here because we can start to build the basic layout for the site. As we add more content types, we'll refactor this file and move logic around. Hugo makes that fairly painless, so we'll accept the cost and proceed. - -Please see the Hugo documentation on template rendering for all the details on determining which template to use. And, as the docs mention, if you're building a single page application (SPA) web site, you can delete all of the other templates and work with just the default single page. That's a refreshing amount of joy right there. - -#### Update the Template File - -``` -$ vi themes/zafta/layouts/_default/single.html - - - - {{ .Title }} - - -

{{ .Title }}

- {{ .Content }} - - -:wq - -$ -``` - -Build the web site and verify the results. - -``` -$ rm -rf public -$ hugo --verbose -INFO: 2014/09/29 Using config file: /Users/quoha/Sites/zafta/config.toml -INFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/themes/zafta/static/ to /Users/quoha/Sites/zafta/public/ -INFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/static/ to /Users/quoha/Sites/zafta/public/ -INFO: 2014/09/29 found taxonomies: map[string]string{"tag":"tags", "category":"categories"} -WARN: 2014/09/29 Unable to locate layout: [404.html theme/404.html] -0 draft content -0 future content -2 pages created -0 tags created -0 categories created -in 4 ms - -$ find public -type f -name '*.html' | xargs ls -l --rw-r--r-- 1 quoha staff 94 Sep 29 22:40 public/index.html --rw-r--r-- 1 quoha staff 125 Sep 29 22:40 public/post/first/index.html --rw-r--r-- 1 quoha staff 0 Sep 29 22:40 public/post/index.html --rw-r--r-- 1 quoha staff 128 Sep 29 22:40 public/post/second/index.html - -$ cat public/post/first/index.html - - - - first - - -

first

-

my first post

- - - - -$ cat public/post/second/index.html - - - - second - - -

second

-

my second post

- - - -$ -``` - -Notice that the posts now have content. You can go to localhost:1313/post/first to verify. - -### Linking to Content - -The posts are on the home page. Let's add a link from there to the post. Since this is the home page, we'll update its template. - -``` -$ vi themes/zafta/layouts/index.html - - - - {{ range first 10 .Data.Pages }} -

{{ .Title }}

- {{ end }} - - -``` - -Build the web site and verify the results. - -``` -$ rm -rf public -$ hugo --verbose -INFO: 2014/09/29 Using config file: /Users/quoha/Sites/zafta/config.toml -INFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/themes/zafta/static/ to /Users/quoha/Sites/zafta/public/ -INFO: 2014/09/29 syncing from /Users/quoha/Sites/zafta/static/ to /Users/quoha/Sites/zafta/public/ -INFO: 2014/09/29 found taxonomies: map[string]string{"tag":"tags", "category":"categories"} -WARN: 2014/09/29 Unable to locate layout: [404.html theme/404.html] -0 draft content -0 future content -2 pages created -0 tags created -0 categories created -in 4 ms - -$ find public -type f -name '*.html' | xargs ls -l --rw-r--r-- 1 quoha staff 149 Sep 29 22:44 public/index.html --rw-r--r-- 1 quoha staff 125 Sep 29 22:44 public/post/first/index.html --rw-r--r-- 1 quoha staff 0 Sep 29 22:44 public/post/index.html --rw-r--r-- 1 quoha staff 128 Sep 29 22:44 public/post/second/index.html - -$ cat public/index.html - - - - -

second

- -

first

- - - - -$ -``` - -### Create a Post Listing - -We have the posts displaying on the home page and on their own page. We also have a file public/post/index.html that is empty. Let's make it show a list of all posts (not just the first ten). - -We need to decide which template to update. This will be a listing, so it should be a list template. Let's take a quick look and see which list templates are available. - -``` -$ find themes/zafta -name list.html | xargs ls -l --rw-r--r-- 1 quoha staff 0 Sep 29 17:31 themes/zafta/layouts/_default/list.html -``` - -As with the single post, we have to decide to update _default/list.html or create post/list.html. We still don't have multiple content types, so let's stay consistent and update the default list template. - -## Creating Top Level Pages - -Let's add an "about" page and display it at the top level (as opposed to a sub-level like we did with posts). - -The default in Hugo is to use the directory structure of the content/ directory to guide the location of the generated html in the public/ directory. Let's verify that by creating an "about" page at the top level: - -``` -$ vi content/about.md -+++ -title = "about" -description = "about this site" -date = "2014-09-27" -slug = "about time" -+++ - -## about us - -i'm speechless -:wq -``` - -Generate the web site and verify the results. - -``` -$ find public -name '*.html' | xargs ls -l --rw-rw-r-- 1 mdhender staff 334 Sep 27 15:08 public/about-time/index.html --rw-rw-r-- 1 mdhender staff 527 Sep 27 15:08 public/index.html --rw-rw-r-- 1 mdhender staff 358 Sep 27 15:08 public/post/first-post/index.html --rw-rw-r-- 1 mdhender staff 0 Sep 27 15:08 public/post/index.html --rw-rw-r-- 1 mdhender staff 342 Sep 27 15:08 public/post/second-post/index.html -``` - -Notice that the page wasn't created at the top level. It was created in a sub-directory named 'about-time/'. That name came from our slug. Hugo will use the slug to name the generated content. It's a reasonable default, by the way, but we can learn a few things by fighting it for this file. - -One other thing. Take a look at the home page. - -``` -$ cat public/index.html - - - -

creating a new theme

-

about

-

second

-

first

- - -``` - -Notice that the "about" link is listed with the posts? That's not desirable, so let's change that first. - -``` -$ vi themes/zafta/layouts/index.html - - - -

posts

- {{ range first 10 .Data.Pages }} - {{ if eq .Type "post"}} -

{{ .Title }}

- {{ end }} - {{ end }} - -

pages

- {{ range .Data.Pages }} - {{ if eq .Type "page" }} -

{{ .Title }}

- {{ end }} - {{ end }} - - -:wq -``` - -Generate the web site and verify the results. The home page has two sections, posts and pages, and each section has the right set of headings and links in it. - -But, that about page still renders to about-time/index.html. - -``` -$ find public -name '*.html' | xargs ls -l --rw-rw-r-- 1 mdhender staff 334 Sep 27 15:33 public/about-time/index.html --rw-rw-r-- 1 mdhender staff 645 Sep 27 15:33 public/index.html --rw-rw-r-- 1 mdhender staff 358 Sep 27 15:33 public/post/first-post/index.html --rw-rw-r-- 1 mdhender staff 0 Sep 27 15:33 public/post/index.html --rw-rw-r-- 1 mdhender staff 342 Sep 27 15:33 public/post/second-post/index.html -``` - -Knowing that hugo is using the slug to generate the file name, the simplest solution is to change the slug. Let's do it the hard way and change the permalink in the configuration file. - -``` -$ vi config.toml -[permalinks] - page = "/:title/" - about = "/:filename/" -``` - -Generate the web site and verify that this didn't work. Hugo lets "slug" or "URL" override the permalinks setting in the configuration file. Go ahead and comment out the slug in content/about.md, then generate the web site to get it to be created in the right place. - -## Sharing Templates - -If you've been following along, you probably noticed that posts have titles in the browser and the home page doesn't. That's because we didn't put the title in the home page's template (layouts/index.html). That's an easy thing to do, but let's look at a different option. - -We can put the common bits into a shared template that's stored in the themes/zafta/layouts/partials/ directory. - -### Create the Header and Footer Partials - -In Hugo, a partial is a sugar-coated template. Normally a template reference has a path specified. Partials are different. Hugo searches for them along a TODO defined search path. This makes it easier for end-users to override the theme's presentation. - -``` -$ vi themes/zafta/layouts/partials/header.html - - - - {{ .Title }} - - -:wq - -$ vi themes/zafta/layouts/partials/footer.html - - -:wq -``` - -### Update the Home Page Template to Use the Partials - -The most noticeable difference between a template call and a partials call is the lack of path: - -``` -{{ template "theme/partials/header.html" . }} -``` -versus -``` -{{ partial "header.html" . }} -``` -Both pass in the context. - -Let's change the home page template to use these new partials. - -``` -$ vi themes/zafta/layouts/index.html -{{ partial "header.html" . }} - -

posts

- {{ range first 10 .Data.Pages }} - {{ if eq .Type "post"}} -

{{ .Title }}

- {{ end }} - {{ end }} - -

pages

- {{ range .Data.Pages }} - {{ if or (eq .Type "page") (eq .Type "about") }} -

{{ .Type }} - {{ .Title }} - {{ .RelPermalink }}

- {{ end }} - {{ end }} - -{{ partial "footer.html" . }} -:wq -``` - -Generate the web site and verify the results. The title on the home page is now "your title here", which comes from the "title" variable in the config.toml file. - -### Update the Default Single Template to Use the Partials - -``` -$ vi themes/zafta/layouts/_default/single.html -{{ partial "header.html" . }} - -

{{ .Title }}

- {{ .Content }} - -{{ partial "footer.html" . }} -:wq -``` - -Generate the web site and verify the results. The title on the posts and the about page should both reflect the value in the markdown file. - -## Add “Date Published” to Posts - -It's common to have posts display the date that they were written or published, so let's add that. The front matter of our posts has a variable named "date." It's usually the date the content was created, but let's pretend that's the value we want to display. - -### Add “Date Published” to the Template - -We'll start by updating the template used to render the posts. The template code will look like: - -``` -{{ .Date.Format "Mon, Jan 2, 2006" }} -``` - -Posts use the default single template, so we'll change that file. - -``` -$ vi themes/zafta/layouts/_default/single.html -{{ partial "header.html" . }} - -

{{ .Title }}

-

{{ .Date.Format "Mon, Jan 2, 2006" }}

- {{ .Content }} - -{{ partial "footer.html" . }} -:wq -``` - -Generate the web site and verify the results. The posts now have the date displayed in them. There's a problem, though. The "about" page also has the date displayed. - -As usual, there are a couple of ways to make the date display only on posts. We could do an "if" statement like we did on the home page. Another way would be to create a separate template for posts. - -The "if" solution works for sites that have just a couple of content types. It aligns with the principle of "code for today," too. - -Let's assume, though, that we've made our site so complex that we feel we have to create a new template type. In Hugo-speak, we're going to create a section template. - -Let's restore the default single template before we forget. - -``` -$ mkdir themes/zafta/layouts/post -$ vi themes/zafta/layouts/_default/single.html -{{ partial "header.html" . }} - -

{{ .Title }}

- {{ .Content }} - -{{ partial "footer.html" . }} -:wq -``` - -Now we'll update the post's version of the single template. If you remember Hugo's rules, the template engine will use this version over the default. - -``` -$ vi themes/zafta/layouts/post/single.html -{{ partial "header.html" . }} - -

{{ .Title }}

-

{{ .Date.Format "Mon, Jan 2, 2006" }}

- {{ .Content }} - -{{ partial "footer.html" . }} -:wq - -``` - -Note that we removed the date logic from the default template and put it in the post template. Generate the web site and verify the results. Posts have dates and the about page doesn't. - -### Don't Repeat Yourself - -DRY is a good design goal and Hugo does a great job supporting it. Part of the art of a good template is knowing when to add a new template and when to update an existing one. While you're figuring that out, accept that you'll be doing some refactoring. Hugo makes that easy and fast, so it's okay to delay splitting up a template. diff --git a/content/posts/goisforlovers.md b/content/posts/goisforlovers.md deleted file mode 100644 index df125d8..0000000 --- a/content/posts/goisforlovers.md +++ /dev/null @@ -1,344 +0,0 @@ -+++ -title = "(Hu)go Template Primer" -description = "" -tags = [ - "go", - "golang", - "templates", - "themes", - "development", -] -date = "2014-04-02" -categories = [ - "Development", - "golang", -] -menu = "main" -+++ - -Hugo uses the excellent [Go][] [html/template][gohtmltemplate] library for -its template engine. It is an extremely lightweight engine that provides a very -small amount of logic. In our experience that it is just the right amount of -logic to be able to create a good static website. If you have used other -template systems from different languages or frameworks you will find a lot of -similarities in Go templates. - -This document is a brief primer on using Go templates. The [Go docs][gohtmltemplate] -provide more details. - -## Introduction to Go Templates - -Go templates provide an extremely simple template language. It adheres to the -belief that only the most basic of logic belongs in the template or view layer. -One consequence of this simplicity is that Go templates parse very quickly. - -A unique characteristic of Go templates is they are content aware. Variables and -content will be sanitized depending on the context of where they are used. More -details can be found in the [Go docs][gohtmltemplate]. - -## Basic Syntax - -Golang templates are HTML files with the addition of variables and -functions. - -**Go variables and functions are accessible within {{ }}** - -Accessing a predefined variable "foo": - - {{ foo }} - -**Parameters are separated using spaces** - -Calling the add function with input of 1, 2: - - {{ add 1 2 }} - -**Methods and fields are accessed via dot notation** - -Accessing the Page Parameter "bar" - - {{ .Params.bar }} - -**Parentheses can be used to group items together** - - {{ if or (isset .Params "alt") (isset .Params "caption") }} Caption {{ end }} - - -## Variables - -Each Go template has a struct (object) made available to it. In hugo each -template is passed either a page or a node struct depending on which type of -page you are rendering. More details are available on the -[variables](/layout/variables) page. - -A variable is accessed by referencing the variable name. - - {{ .Title }} - -Variables can also be defined and referenced. - - {{ $address := "123 Main St."}} - {{ $address }} - - -## Functions - -Go template ship with a few functions which provide basic functionality. The Go -template system also provides a mechanism for applications to extend the -available functions with their own. [Hugo template -functions](/layout/functions) provide some additional functionality we believe -are useful for building websites. Functions are called by using their name -followed by the required parameters separated by spaces. Template -functions cannot be added without recompiling hugo. - -**Example:** - - {{ add 1 2 }} - -## Includes - -When including another template you will pass to it the data it will be -able to access. To pass along the current context please remember to -include a trailing dot. The templates location will always be starting at -the /layout/ directory within Hugo. - -**Example:** - - {{ template "chrome/header.html" . }} - - -## Logic - -Go templates provide the most basic iteration and conditional logic. - -### Iteration - -Just like in Go, the Go templates make heavy use of range to iterate over -a map, array or slice. The following are different examples of how to use -range. - -**Example 1: Using Context** - - {{ range array }} - {{ . }} - {{ end }} - -**Example 2: Declaring value variable name** - - {{range $element := array}} - {{ $element }} - {{ end }} - -**Example 2: Declaring key and value variable name** - - {{range $index, $element := array}} - {{ $index }} - {{ $element }} - {{ end }} - -### Conditionals - -If, else, with, or, & and provide the framework for handling conditional -logic in Go Templates. Like range, each statement is closed with `end`. - - -Go Templates treat the following values as false: - -* false -* 0 -* any array, slice, map, or string of length zero - -**Example 1: If** - - {{ if isset .Params "title" }}

{{ index .Params "title" }}

{{ end }} - -**Example 2: If -> Else** - - {{ if isset .Params "alt" }} - {{ index .Params "alt" }} - {{else}} - {{ index .Params "caption" }} - {{ end }} - -**Example 3: And & Or** - - {{ if and (or (isset .Params "title") (isset .Params "caption")) (isset .Params "attr")}} - -**Example 4: With** - -An alternative way of writing "if" and then referencing the same value -is to use "with" instead. With rebinds the context `.` within its scope, -and skips the block if the variable is absent. - -The first example above could be simplified as: - - {{ with .Params.title }}

{{ . }}

{{ end }} - -**Example 5: If -> Else If** - - {{ if isset .Params "alt" }} - {{ index .Params "alt" }} - {{ else if isset .Params "caption" }} - {{ index .Params "caption" }} - {{ end }} - -## Pipes - -One of the most powerful components of Go templates is the ability to -stack actions one after another. This is done by using pipes. Borrowed -from unix pipes, the concept is simple, each pipeline's output becomes the -input of the following pipe. - -Because of the very simple syntax of Go templates, the pipe is essential -to being able to chain together function calls. One limitation of the -pipes is that they only can work with a single value and that value -becomes the last parameter of the next pipeline. - -A few simple examples should help convey how to use the pipe. - -**Example 1 :** - - {{ if eq 1 1 }} Same {{ end }} - -is the same as - - {{ eq 1 1 | if }} Same {{ end }} - -It does look odd to place the if at the end, but it does provide a good -illustration of how to use the pipes. - -**Example 2 :** - - {{ index .Params "disqus_url" | html }} - -Access the page parameter called "disqus_url" and escape the HTML. - -**Example 3 :** - - {{ if or (or (isset .Params "title") (isset .Params "caption")) (isset .Params "attr")}} - Stuff Here - {{ end }} - -Could be rewritten as - - {{ isset .Params "caption" | or isset .Params "title" | or isset .Params "attr" | if }} - Stuff Here - {{ end }} - - -## Context (aka. the dot) - -The most easily overlooked concept to understand about Go templates is that {{ . }} -always refers to the current context. In the top level of your template this -will be the data set made available to it. Inside of a iteration it will have -the value of the current item. When inside of a loop the context has changed. . -will no longer refer to the data available to the entire page. If you need to -access this from within the loop you will likely want to set it to a variable -instead of depending on the context. - -**Example:** - - {{ $title := .Site.Title }} - {{ range .Params.tags }} -
  • {{ . }} - {{ $title }}
  • - {{ end }} - -Notice how once we have entered the loop the value of {{ . }} has changed. We -have defined a variable outside of the loop so we have access to it from within -the loop. - -# Hugo Parameters - -Hugo provides the option of passing values to the template language -through the site configuration (for sitewide values), or through the meta -data of each specific piece of content. You can define any values of any -type (supported by your front matter/config format) and use them however -you want to inside of your templates. - - -## Using Content (page) Parameters - -In each piece of content you can provide variables to be used by the -templates. This happens in the [front matter](/content/front-matter). - -An example of this is used in this documentation site. Most of the pages -benefit from having the table of contents provided. Sometimes the TOC just -doesn't make a lot of sense. We've defined a variable in our front matter -of some pages to turn off the TOC from being displayed. - -Here is the example front matter: - -``` ---- -title: "Permalinks" -date: "2013-11-18" -aliases: - - "/doc/permalinks/" -groups: ["extras"] -groups_weight: 30 -notoc: true ---- -``` - -Here is the corresponding code inside of the template: - - {{ if not .Params.notoc }} -
    - {{ .TableOfContents }} -
    - {{ end }} - - - -## Using Site (config) Parameters -In your top-level configuration file (eg, `config.yaml`) you can define site -parameters, which are values which will be available to you in chrome. - -For instance, you might declare: - -```yaml -params: - CopyrightHTML: "Copyright © 2013 John Doe. All Rights Reserved." - TwitterUser: "spf13" - SidebarRecentLimit: 5 -``` - -Within a footer layout, you might then declare a `