Giter Club home page Giter Club logo

ksoup's Introduction

Ksoup - Kotlin Multiplatform HTML Parser

Ksoup is a lightweight Kotlin Multiplatform library for parsing HTML, extracting HTML tags, attributes, and text, and encoding and decoding HTML entities.

Kotlin MohamedRejeb Apache-2.0 BuildPassing Maven Central

Slide 16_9 - 1 (1)

Features

  • Parse HTML from String
  • Extract HTML tags, attributes, and text
  • Encode and decode HTML entities
  • Lightweight and does not depend on any other library
  • Kotlin Multiplatform support
  • Fast and efficient
  • Unit tested

Installation

Maven Central

Add the dependency below to your module's build.gradle.kts or build.gradle file:

Kotlin version Ksoup version
1.9.2x 0.3.x
1.9.x 0.2.1
1.8.x 0.1.4
val version = "0.3.1"

// For parsing HTML
implementation("com.mohamedrejeb.ksoup:ksoup-html:$version")

// Only for encoding and decoding HTML entities 
implementation("com.mohamedrejeb.ksoup:ksoup-entities:$version")

Usage

Parsing HTML

To parse HTML from a String, use the KsoupHtmlParser class, and provide an implementation of the KsoupHtmlHandler interface, and a KsoupHtmlOptions object. Both of them are optional, you can use the default ones if you want.

KsoupHtmlParser

You can create a parser using the KsoupHtmlParser(), there are several methods that you can use, for example write to parse a String, and end to close the parser when you are done:

val ksoupHtmlParser = KsoupHtmlParser()

// String to parse
val html = "<h1>My Heading</h1>"

// Pass the HTML to the parser (It is going to parse the HTML and call the callbacks)
ksoupHtmlParser.write(html)

// Close the parser when you are done
ksoupHtmlParser.end()

KsoupHtmlHandler

You can directly implement KsoupHtmlHandler interface or use KsoupHtmlHandler.Builder():

// Implement `KsoupHtmlHandler` interface
val firstHandler = object : KsoupHtmlHandler {
    override fun onOpenTag(name: String, attributes: Map<String, String>, isImplied: Boolean) {
        println("Open tag: $name")
    }
}

// Use `KsoupHtmlHandler.Builder()`
val secondHandler = KsoupHtmlHandler
    .Builder()
    .onOpenTag { name, attributes, isImplied ->
        println("Open tag: $name")
    }
    .build()

There are several methods that you can override, for example is you want to just extract the text from the HTML, you can override the onText method:

// String to parse
val html = """
    <html>
        <head>
            <title>My Title</title>
        </head>
        <body>
            <h1>My Heading</h1>
            <p>My paragraph.</p>
        </body>
    </html>
""".trimIndent()

// String to store the extracted text
var string = ""

// Create a handler
val handler = KsoupHtmlHandler
    .Builder()
    .onText { text ->
        string += text
    }
    .build()

// Create a parser
val ksoupHtmlParser = KsoupHtmlParser(
    handler = handler,
)

// Pass the HTML to the parser (It is going to parse the HTML and call the callbacks)
ksoupHtmlParser.write(html)

// Close the parser when you are done
ksoupHtmlParser.end()

You can also use onOpenTag and onCloseTag to know when a tag is opened or closed, it can be used for scrapping data from a website or powering a rich text editor, Also you can use onComment to know when a comment is found in the HTML and onAttribute to know when attributes are found in a tag.

KsoupHtmlOptions

You can also pass KsoupHtmlOptions to the parser to change the behavior of the parser, you can for example disable the decoding of HTML entities which is enabled by default:

val options = KsoupHtmlOption(
    decodeEntities = false,
)

Encoding and Decoding HTML Entities

You can use the KsoupEntities class to encode and decode HTML entities:

// Encode HTML entities
val encoded = KsoupEntities.encodeHtml("Hello & World") // return: Hello &amp; World

// Decode HTML entities
val decoded = KsoupEntities.decodeHtml("Hello &amp; World") // return: Hello & World

KsoupEntities also provides methods to encode and decode only XML entities or HTML4. The KsoupEntities class is available in the ksoup-entities module.

Both encodeHtml and decodeHtml methods support all HTML5 entities, XML entities, and HTML4 entities.

Coming Features

  • Add clear documentation
  • Add Markdown parser

Contribution

If you've found an error in this sample, please file an issue.
Feel free to help out by sending a pull request ❤️.

Code of Conduct

Find this library useful? ❤️

Support it by joining stargazers for this repository. ⭐
Also, follow me on GitHub for more libraries! 🤩

You can always

License

Copyright 2023 Mohamed Rejeb

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

ksoup's People

Contributors

ire4ever1190 avatar koalas11 avatar mohamedrejeb avatar spacecowboy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ksoup's Issues

Parser.unescapeEntities equivalent

It would be immensely helpful if the ksoup-entites module would provide an Parser.unescapeEntities equivalent Jsoup API:

https://jsoup.org/apidocs/org/jsoup/parser/Parser.html#unescapeEntities(java.lang.String,boolean)

With that one you can unescape all of the &#1234; entities.

My use case is that I have an RSS Reader and often times even though it's not required the content is HTML encoded and hence I need to unescape it. For instance here's on such feed:

https://lexfridman.com/feed/podcast/

Note though that ideally any unicode would be supported, here are some more feeds which use a lot of escaped HTML entites:

https://vandal.elespanol.com/xml.cgi
https://open.firstory.me/rss/user/cklqae6gy388f0892i2qmv851
https://blog.codinghorror.com/rss/
https://www.ivoox.com/finanzas-personales-libertad-financiera_fg_f1703990_filtro_1.xml

Decoder is failing to decode &rsquo;

Example test

class KsoupTest {
    @Test
    fun rsquo() {
        val text = "laptop, it&rsquo;s probably"
        val expected = "laptop, it’s probably"

        assertEquals(expected, KsoupEntities.decodeHtml(text))
    }
}

Output:

Expected :laptop, it’s probably
Actual   :laptop, it&rsquo;s probably

com.mohamedrejeb.ksoup:ksoup-entites:0.3.1

I had the same problem with 0.3.0 but didn't bother. Would it be possible that you publish all of the modules with the same version? That's what all of the popular libraries do (OkHttp, Retrofit, Sqldelight, etc)

Add XPath search

Since there is no wiki for this library yet. I'd like to know if there is a functionality to search for the element in parsed tree via xpath.
If there is not, that would be a great enhancement for your awesome library.

KsoupHtmlParser throws IndexOutOfBounds

The following test case fails:

@Test fun indexOutOfBounds() {
  KsoupHtmlParser(
    handler = Builder().build()
  ).parseComplete("""
<h3 class="wp-block-heading has-text-align-center">For people who want to see the world without f***ing up their mental, physical &amp; financial health</h3>



<h2 class="wp-block-heading">Table Of Contents</h2>



<ul>
<li><a href="#parisian-anecdote"><strong>Getting Lost In A City &#8211; A Parisian Anecdote</strong></a></li>



<li><a href="#why-should-i-journal"><strong>So Why Do I Journal</strong></a></li>



<li><strong><a href="#journalling-tips">Journaling Tips &amp; Some Background On My Approach</a></strong></li>



<li><strong><a href="#daily-journal-template">My Daily Journal Template</a></strong>
<ul>
<li><a href="#happy-about">What Am I Happy About From Yesterday?</a></li>



<li><a href="#things-to-improve">What Would I Like To Improve Today?</a></li>



<li><a href="#gratitude-journalling">Things I&#8217;m Grateful For</a></li>



<li><a href="#3-main-focuses">3 Main Focuses</a></li>



<li><a href="#additional-notes">My Notes Section</a></li>
</ul>
</li>



<li><a href="#quarterly-journalling"><strong>My Quarterly Journalling Practices</strong></a></li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="parisian-anecdote">Getting Lost In A City &#8211; A Parisian Anecdote</h2>



<p>I&#8217;m writing this from a cafe here in Paris, a proper Parisian cafe with the colored chairs sitting two by each other behind small round tables. In front of me the city is buzzing, There&#8217;s a swarm of cars, motorcycles, bikes, mentally ill people yelling. </p>



<p>It&#8217;s a controlled anarchy that I love. The reason I love cities. Then add to this the architecture, culture, cuisine and language of France and you have Paris. Which is without a doubt one of my favorite cities in the world. <a href="https://digitalnomadlifestyle.com/2022/11/29/the-complete-digital-nomad-guide-for-paris/">See my complete digital nomad guide for Paris here.</a></p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="I do miss working from Parisian cafe’s…" width="750" height="422" src="https://www.youtube.com/embed/agRQ0t8Bl70?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
</div><figcaption class="wp-element-caption">A shot from one of my favorite cafe&#8217;s to work from in Paris.</figcaption></figure>



<p>I&#8217;ve been taking intensive French classes, which has me at a school for 5 hours a day speaking nothing but French and learning about pronunciation, vocabulary, and grammar (the latter is a bit of a nightmare). </p>



<p>I got to Paris nearly a week ago and I&#8217;ve been wrapped up in it all. Wrapped up in the energy of the city, the buzz, the eagerness to get my French back to where it was before, and even better.</p>



<p>The energy of this city is palpable to me, and I feel alive. I feel alive the same way I did hiking through the German &amp; Austrian Alps (<a href="https://digitalnomadlifestyle.com/2022/10/16/austria-digital-nomad-guide/">see my Austrian digital nomad guide here</a>) or spending time with women I&#8217;ve been in love with (<a href="https://digitalnomadlifestyle.com/category/dating-while-traveling/">see my travel love stories here</a>). Food tastes better. The buildings and people I&#8217;d normally let fall into the background unnoticed, I&#8217;m appreciating. I feel alive.</p>



<figure class="wp-block-pullquote"><blockquote><p>It&#8217;s easy to get caught up in this high, to lose sight of my emotional, physical &amp; financial well-being and get wrapped up in the sights, sounds and people around me. </p></blockquote></figure>



<p>I&#8217;ve done this a million times. As someone without any strong ties to any one place I can live my entire life chasing novelty. </p>



<p>If I get tired of a woman I&#8217;m dating, just find a new one. If I get tired of a place I&#8217;m at just move to a new spot. If I get tired of the friends I&#8217;m around, get new ones.</p>



<p>I&#8217;ve gone through dozens of cities, friends and women only to realize that if I can&#8217;t find stability and peace in my travels then I&#8217;ll remain unsatisfied and alone.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img data-attachment-id="1404" data-permalink="https://digitalnomadlifestyle.com/2022/06/26/dating-while-traveling-pt-2/1545597_743859895641539_12666155_n-1/" data-orig-file="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2022/06/1545597_743859895641539_12666155_n-1-3972726808-1656251480843.jpg?fit=540%2C787&amp;ssl=1" data-orig-size="540,787" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="1545597_743859895641539_12666155_n (1)" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2022/06/1545597_743859895641539_12666155_n-1-3972726808-1656251480843.jpg?fit=206%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2022/06/1545597_743859895641539_12666155_n-1-3972726808-1656251480843.jpg?fit=540%2C787&amp;ssl=1" decoding="async" loading="lazy" src="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2022/06/1545597_743859895641539_12666155_n-1-3972726808-1656251480843.jpg?resize=347%2C505&#038;ssl=1" alt="Dating While Traveling - Thailand" class="wp-image-1404" width="347" height="505" srcset="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2022/06/1545597_743859895641539_12666155_n-1-3972726808-1656251480843.jpg?w=540&amp;ssl=1 540w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2022/06/1545597_743859895641539_12666155_n-1-3972726808-1656251480843.jpg?resize=206%2C300&amp;ssl=1 206w" sizes="(max-width: 347px) 100vw, 347px" data-recalc-dims="1" /></figure></div>


<p class="has-text-align-center"><em>A photo from Thailand with my then girlfriend, <a href="https://digitalnomadlifestyle.com/category/dating-while-traveling/">click here to read my dating and traveling stories</a></em></p>



<p>Instead of looking inward at my responsibility for the lack of joy, fulfillment, connection I&#8217;ll project the issue externally. </p>



<p>It&#8217;s X&#8217;s fault that I&#8217;m not feeling fulfilled from this relationship. It&#8217;s the shitty weather here that&#8217;s making me depressed. It&#8217;s because of my emotionally distant friends that I&#8217;m not feeling connected.</p>



<p>You can always find an external thing to blame your dissatisfaction on, and if you&#8217;re like me then you can keep changing those external things, until you&#8217;re exhausted and nowhere left to look but inside.</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="4 Tips For Self Discipline" width="750" height="422" src="https://www.youtube.com/embed/XCT1vmvGlyo?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
</div><figcaption class="wp-element-caption">A video I shot up in Franschhoek, South Africa. A country I love but where I was guilty of losing sight of balancing my mental / spiritual health.  <a href="https://digitalnomadlifestyle.com/2022/03/09/the-complete-digital-nomad-guide-to-cape-town-south-africa/">Check out my digital nomad guide to Cape Town here.</a></figcaption></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="why-should-i-journal">So Why Do I Journal?</h2>



<p>I journal for a multitude of reasons, but the biggest reason is to (try to) stay calm and centered regardless of what&#8217;s going on around me.</p>



<p>Journalling gives me more insight into how I&#8217;m feeling, what I&#8217;m dissatisfied with and how to improve my mood for the day. </p>



<p>That keeps me from blaming my dissatisfaction on the world around me, it gives me the power to control my emotions.</p>



<p>In addition to this, there are some other benefits I get from journalling</p>



<blockquote class="wp-block-quote">
<ul>
<li>A daily reminder about what&#8217;s important to me (through reviewing my intentions, HW and goals)</li>



<li>Setting my mind in a positive framework (through gratitude)</li>



<li>Checking in on my emotions and bodily sensations</li>



<li>Making sure that I&#8217;m taking care of myself, and getting my major needs met</li>



<li>Making sure that I&#8217;m working toward my mental / spiritual, physical &amp; financial goals</li>



<li>A space for me to discover why I&#8217;m feeling the way I am</li>
</ul>
</blockquote>



<p class="has-text-align-center"><em>A video from my last trip to Costa Rica. Where I started getting more serious about my journalling</em></p>



<figure class="wp-block-embed aligncenter is-type-rich is-provider-instagram wp-block-embed-instagram"><div class="wp-block-embed__wrapper">
<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-permalink="https://www.instagram.com/reel/CXykFjuACmX/?utm_source=ig_embed&amp;utm_campaign=loading" data-instgrm-version="14" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:16px;"> <a href="https://www.instagram.com/reel/CXykFjuACmX/?utm_source=ig_embed&amp;utm_campaign=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> <div style=" display: flex; flex-direction: row; align-items: center;"> <div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;"></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;"></div></div></div><div style="padding: 19% 0;"></div> <div style="display:block; height:50px; margin:0 auto 12px; width:50px;"><svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-511.000000, -20.000000)" fill="#000000"><g><path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631"></path></g></g></g></svg></div><div style="padding-top: 8px;"> <div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;">View this post on Instagram</div></div><div style="padding: 12.5% 0;"></div> <div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;"><div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);"></div> <div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;"></div> <div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);"></div></div><div style="margin-left: 8px;"> <div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;"></div> <div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)"></div></div><div style="margin-left: auto;"> <div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);"></div> <div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);"></div> <div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);"></div></div></div> <div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;"></div> <div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;"></div></div></a><p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;"><a href="https://www.instagram.com/reel/CXykFjuACmX/?utm_source=ig_embed&amp;utm_campaign=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by Digital Nomad Lifestyle (@officialdigitalnomadlifestyle)</a></p></div></blockquote><script async src="//platform.instagram.com/en_US/embeds.js"></script>
</div></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="journalling-tips">Important Notes, Tips &amp; Explanations About Journalling</h2>



<ol>
<li><strong>I do not journal daily, or complete all of this tasks as much as I&#8217;d like. </strong>
<ul>
<li>I try my hardest, if I skip a day or two I don&#8217;t give up on journaling, I get back on the horse and try again. It&#8217;s the same idea if you want <a href="https://digitalnomadlifestyle.com/2022/10/26/how-to-stay-healthy-while-traveling/">to stay fit while traveling</a>.</li>
</ul>
</li>



<li><strong>The goal of journaling isn&#8217;t to fill everything out 100% and fully optimize my morning process, etc. the goal is to better understand myself, what gives me energy, what takes energy away and reminding myself about what I truly care about.</strong>
<ul>
<li>Even with the world open to me, it&#8217;s incredible how easy I can<a href="https://digitalnomadlifestyle.com/2022/05/22/social-anxiety-while-traveling/"> &#8220;optimize&#8221; myself into a prison.</a> I want to feel fulfilled by my journalling, not imprisoned by it</li>
</ul>
</li>



<li><strong>This template isn&#8217;t set in stone</strong>
<ul>
<li>I started journalling regularly when I started <a href="https://lrossmarketingconsulting.com/">my digital marketing business</a> four years ago. Over the years, I&#8217;ve changed my approach to journaling and I&#8217;ll likely update it a few more times in the next 4 years.</li>



<li>I know one thing though, I will be journaling for the rest of my life</li>
</ul>
</li>



<li><strong>But journalling in the morning takes up a lot of time, I got things to do!</strong>
<ul>
<li>I get this, and I even skip my journaling in the morning (although I try my hardest never to skip two days in a row)</li>



<li>However, taking the time to sit and journal can be huge in priming your mind to stay on track. If you can sit down and complete a journal process it can help you stay on track and not get distracted when you&#8217;re working on other tasks throughout the day.</li>
</ul>
</li>
</ol>



<p class="has-text-align-center"><em>A video of me writing in my journal in a beautiful cabin in Santa Helena, Colombia</em></p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Beautiful Cabin In Sant Helena, Colombia" width="750" height="422" src="https://www.youtube.com/embed/qyz0jYfN1Zg?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
</div></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="daily-journal-template">My Daily Journal Template</h2>



<ol>
<li>What Am I Happy About From Yesterday?</li>



<li>What Did I Do Yesterday That I&#8217;d Like To Improve On Today?</li>



<li>Gratitude &#8211; 5 Things I&#8217;m Grateful For Right Now</li>



<li>3 Main Foci
<ul>
<li>Mental / Spiritual Health
<ul>
<li>Healthy Ways To Get Connection</li>



<li>Healthy Ways To Get Novelty</li>



<li>Healthy Ways To Get Comfort</li>



<li>Healthy Ways To Get Validation</li>
</ul>
</li>



<li>Physical Health</li>



<li>Career / Financial Health</li>
</ul>
</li>



<li>My Notes Section</li>
</ol>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img data-attachment-id="2690" data-permalink="https://digitalnomadlifestyle.com/2023/04/28/daily-journalling-templates-travel/img_6445/" data-orig-file="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/IMG_6445.jpg?fit=3023%2C2250&amp;ssl=1" data-orig-size="3023,2250" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;1.5&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;iPhone 13 Pro Max&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1681034843&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;5.7&quot;,&quot;iso&quot;:&quot;40&quot;,&quot;shutter_speed&quot;:&quot;0.0043290043290043&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="IMG_6445" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/IMG_6445.jpg?fit=300%2C223&amp;ssl=1" data-large-file="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/IMG_6445.jpg?fit=750%2C558&amp;ssl=1" decoding="async" loading="lazy" src="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/IMG_6445.jpg?resize=440%2C327&#038;ssl=1" alt="Example Daily Journal Template" class="wp-image-2690" width="440" height="327" srcset="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/IMG_6445.jpg?w=3023&amp;ssl=1 3023w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/IMG_6445.jpg?resize=300%2C223&amp;ssl=1 300w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/IMG_6445.jpg?resize=1024%2C762&amp;ssl=1 1024w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/IMG_6445.jpg?resize=768%2C572&amp;ssl=1 768w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/IMG_6445.jpg?resize=1536%2C1143&amp;ssl=1 1536w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/IMG_6445.jpg?resize=2048%2C1524&amp;ssl=1 2048w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/IMG_6445.jpg?resize=200%2C150&amp;ssl=1 200w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/IMG_6445.jpg?resize=1200%2C893&amp;ssl=1 1200w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/IMG_6445.jpg?resize=1568%2C1167&amp;ssl=1 1568w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/IMG_6445.jpg?w=2250&amp;ssl=1 2250w" sizes="(max-width: 440px) 100vw, 440px" data-recalc-dims="1" /></figure></div>


<p class="has-text-align-center"><em>A snapshot of a couple days in my journal</em></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Breakdown of The Sections Of My Daily Journaling</h2>



<h3 class="wp-block-heading" id="happy-about">What Am I Happy About From Yesterday?</h3>



<p>Admittedly, I&#8217;m not great at always doing this part and the next. But this can be a great way to kickstart my gratitude for the day, and also build some positive momentum going into the day.</p>



<h3 class="wp-block-heading" id="things-to-improve">What Did I Do Yesterday That I&#8217;d Like To Improve On Today?</h3>



<figure class="wp-block-pullquote"><blockquote><p>I always tell my employees that making the same mistakes over and over again are how businesses fail. It&#8217;s not too different for people either, making the same mistakes over and over again is a recipe for disaster.</p></blockquote></figure>



<p>This process can really expedite identifying recurring issues and shortening their lifetime.</p>



<h3 class="wp-block-heading" id="gratitude-journalling">Gratitude &#8211; 5 Things I&#8217;m Grateful For Right Now</h3>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img data-attachment-id="359" data-permalink="https://digitalnomadlifestyle.com/2021/07/12/cycling-from-athens-to-istanbul/bike-in-sunrise-near-palamanos/" data-orig-file="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2021/07/Bike-in-sunrise-near-Palamanos.jpg?fit=4032%2C3024&amp;ssl=1" data-orig-size="4032,3024" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;1.73&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;Pixel 5&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1626069104&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;4.38&quot;,&quot;iso&quot;:&quot;260&quot;,&quot;shutter_speed&quot;:&quot;0.042016&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="Bike in sunrise near Palamanos" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2021/07/Bike-in-sunrise-near-Palamanos.jpg?fit=300%2C225&amp;ssl=1" data-large-file="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2021/07/Bike-in-sunrise-near-Palamanos.jpg?fit=750%2C563&amp;ssl=1" decoding="async" loading="lazy" src="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2021/07/Bike-in-sunrise-near-Palamanos.jpg?resize=569%2C427&#038;ssl=1" alt="Cycling Through Greece - Katerini" class="wp-image-359" width="569" height="427" srcset="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2021/07/Bike-in-sunrise-near-Palamanos.jpg?resize=1024%2C768&amp;ssl=1 1024w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2021/07/Bike-in-sunrise-near-Palamanos.jpg?resize=300%2C225&amp;ssl=1 300w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2021/07/Bike-in-sunrise-near-Palamanos.jpg?resize=768%2C576&amp;ssl=1 768w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2021/07/Bike-in-sunrise-near-Palamanos.jpg?resize=1536%2C1152&amp;ssl=1 1536w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2021/07/Bike-in-sunrise-near-Palamanos.jpg?resize=2048%2C1536&amp;ssl=1 2048w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2021/07/Bike-in-sunrise-near-Palamanos.jpg?resize=1200%2C900&amp;ssl=1 1200w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2021/07/Bike-in-sunrise-near-Palamanos.jpg?resize=800%2C600&amp;ssl=1 800w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2021/07/Bike-in-sunrise-near-Palamanos.jpg?resize=400%2C300&amp;ssl=1 400w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2021/07/Bike-in-sunrise-near-Palamanos.jpg?resize=200%2C150&amp;ssl=1 200w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2021/07/Bike-in-sunrise-near-Palamanos.jpg?resize=1568%2C1176&amp;ssl=1 1568w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2021/07/Bike-in-sunrise-near-Palamanos.jpg?w=2250&amp;ssl=1 2250w" sizes="(max-width: 569px) 100vw, 569px" data-recalc-dims="1" /></figure></div>


<p class="has-text-align-center"><em>A shot from my <a href="https://digitalnomadlifestyle.com/2021/07/12/cycling-from-athens-to-istanbul/">bike ride through Greece &amp; Turkey</a>, gratitude is a necessity for these rides</em></p>



<p><strong>A couple tips to gratitude</strong></p>



<ol>
<li>Try not to repeat the same things every morning &#8211; this is easy to do, and can keep you from fully experiencing the practice.</li>



<li>Try to list out the details of what you&#8217;re grateful for, as well as why you&#8217;re grateful for it. 
<ul>
<li>Here&#8217;s an example &#8211; <em>I&#8217;m grateful for this cafe I&#8217;m at.</em> Vs. <em>I&#8217;m grateful for this cafe I&#8217;m at, the natural lighting that it has, the trees outside the windows, the kindness of the staff and the beautiful music they play, it makes me feel inspired and brings me joy.</em></li>
</ul>
</li>



<li>Notice your emotions, gratitude is an emotion if you&#8217;re not feeling any changes to your emotions you may need to switch things up.</li>



<li>You can also use gratitude as an affirmation of things to come. I&#8217;m grateful that (X) injury will be fixed, I&#8217;m grateful that I&#8217;ll get that raise by the end of the month, etc.</li>



<li>One thing I started doing on my longer bike rides when I was having a hard time switching over into gratitude was what I call gratitude bombs.
<ul>
<li>This is where I&#8217;ll spend as much time as it takes listing out everything I&#8217;m grateful for until I can start to feel the positivity creeping in. Sometimes you&#8217;re listing things out for 5 minutes, but eventually your mind does come around.</li>
</ul>
</li>
</ol>



<h3 class="wp-block-heading" id="3-main-focuses">3 Main Foci</h3>



<p>A lot of journal prompts will have you outline your 1 &#8211; 5 goals for the day, I really liked this idea and I transformed it a bit. </p>



<p>Everyday I journal I want to outline what I&#8217;m going to do today for my mental / spiritual health, my physical health and finally my financial / career health.</p>



<p>This order is very important to me. </p>



<p>My Mental health is #1, my physical health comes second, and then my career and financial health. I don&#8217;t always get this order right, but it&#8217;s a big intention of mine.</p>



<figure class="wp-block-pullquote"><blockquote><p>I don&#8217;t care how much money I make, if I&#8217;m not in the physical shape I want to be in, I&#8217;m not going to be fulfilled. <br>I can also make a bunch of money and be in great shape, but if I&#8217;m not taking care of my mental health and I&#8217;m feeling miserable that&#8217;s not the life I want to live either.</p></blockquote></figure>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-attachment-id="2748" data-permalink="https://digitalnomadlifestyle.com/2023/04/28/daily-journalling-templates-travel/11752432_1084073454953513_3741587307966287593_n/" data-orig-file="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/11752432_1084073454953513_3741587307966287593_n.jpg?fit=536%2C625&amp;ssl=1" data-orig-size="536,625" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="11752432_1084073454953513_3741587307966287593_n" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/11752432_1084073454953513_3741587307966287593_n.jpg?fit=257%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/11752432_1084073454953513_3741587307966287593_n.jpg?fit=536%2C625&amp;ssl=1" decoding="async" loading="lazy" width="536" height="625" src="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/11752432_1084073454953513_3741587307966287593_n.jpg?resize=536%2C625&#038;ssl=1" alt="ripped dude on a beach" class="wp-image-2748" srcset="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/11752432_1084073454953513_3741587307966287593_n.jpg?w=536&amp;ssl=1 536w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/11752432_1084073454953513_3741587307966287593_n.jpg?resize=257%2C300&amp;ssl=1 257w" sizes="(max-width: 536px) 100vw, 536px" data-recalc-dims="1" /></figure></div>


<p class="has-text-align-center"><em>A shot of me when I was in Vietnam. In great shape, but largely ignoring my mental health. <a href="https://digitalnomadlifestyle.com/about/">Learn more about my journey to being a digital nomad here.</a></em></p>



<p>So I start my mornings reinforcing what&#8217;s most important to me.</p>



<ul>
<li>First my mental spiritual health</li>



<li>Then what I&#8217;m going to do for my physical health &#8211; <em><a href="https://digitalnomadlifestyle.com/2022/10/26/how-to-stay-healthy-while-traveling/">interested in staying fit while traveling? Check out my guide here.</a></em></li>



<li>And finally what I&#8217;m going to do for my career / financial health</li>
</ul>



<blockquote class="wp-block-quote">
<p><em>Looking back now, could I have achieved the financial / career success I have now if I had been more focused on my mental health while I was climbing the career ladder? </em></p>



<p><em>I don&#8217;t know&#8230; so maybe my lack of introspection served me for building a career, but at this point I&#8217;m not interested in regularly trading happiness today for money tomorrow.</em></p>
</blockquote>



<h4 class="wp-block-heading">My Mental / Spiritual Health</h4>



<p>Here&#8217;s a breakdown of what I try to do everyday</p>



<ul>
<li>15 Minutes Meditation &#8211; <em>trying to focus on my bodily sensations and emotions and less on my thoughts</em></li>



<li>Filling out the emotions I&#8217;m feeling, where I&#8217;m feeling them in my body and the need I&#8217;m either getting or not getting that&#8217;s causing me to feel these feelings
<ul>
<li>This practice was introduced to me from my therapist, and it originally comes from The <a href="https://www.cnvc.org/">Center For Non-violent Communication</a>. 
<ul>
<li>I&#8217;m not super strong at recognizing what emotions I&#8217;m feeling and why I&#8217;m feeling them so starting off every morning by checking in with my emotions is a good way to prime me to stay in tuned with my emotions throughout the day</li>
</ul>
</li>



<li>Re-reading my intentions <em>(more on this below)</em></li>



<li>Re-reading my 4 &#8211; 8 week goals <em>(more on this below)</em></li>



<li>Re-reading the insights and HW I got from my previous therapy session <em>(more on this below)</em></li>
</ul>
</li>
</ul>



<ul>
<li>After this I&#8217;ll outline how I plan to get 4 of my most common needs met that day. After <a href="https://digitalnomadlifestyle.com/category/overly-personal-emotional-stuff/my-journey-w-celibacy-semen-retention/">my attempt with celibacy</a>, I realized that if I&#8217;m not getting the following needs met I turn to promiscuity. 
<ul>
<li><strong>Validation</strong> &#8211; Feeling good enough</li>



<li><strong>Comfort</strong> &#8211; Feeling comfortable / far from anxiety, stress</li>



<li><strong>Connection </strong>&#8211; Feeling connected and close to others. <em>This can be tough as a nomad, so I interviewed 6 other full-time travelers and <a href="https://digitalnomadlifestyle.com/2022/08/10/how-to-build-community-connection-as-a-digital-nomad/">came up with this guide to build community &amp; connection while traveling.</a></em></li>



<li><strong>Novelty</strong> &#8211; The excitement of new experiences</li>
</ul>
</li>
</ul>



<p class="has-text-align-center"><em>A shot of me journalling in Cancun, Mexico. Where I started getting more in touch with my emotions. Interested in digital nomadding in Mexico, check out my guide for <a href="https://digitalnomadlifestyle.com/2022/07/03/mexico-city-the-complete-digital-nomad-guide/">Mexico City</a> or <a href="https://digitalnomadlifestyle.com/2022/06/12/the-complete-digital-nomad-guide-playa-del-carmen-mexico/">Playa Del Carmen</a>.</em></p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Journalling in Cancun" width="750" height="422" src="https://www.youtube.com/embed/YAThDw8Jh04?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
</div></figure>



<figure class="wp-block-pullquote"><blockquote><p>I would recommend everyone who regularly engages in behaviors they want to change to take some time to look through <a href="https://www.cnvc.org/training/resource/needs-inventory">this list of human needs</a> and figure out which needs they&#8217;re getting met through those behaviors and how they can find healthier ways to get those needs met.</p></blockquote></figure>



<p>After struggling with overeating, drinking to feel better and relying on sex and women to feel good I&#8217;ve started outlining daily how I can get my most important needs met and it helps keep the urges (more) under control. </p>



<p>Do I still slip up? Absolutely, but outlining healthier ways to get these needs met daily has really helped me in mitigating the occurrences and duration of my slip-ups.</p>



<p>So everyday I try to outline 1 &#8211; 3 healthier ways I can get these 4 needs met.</p>



<h4 class="wp-block-heading">My Physical Goals For The Day</h4>



<p class="has-text-align-center"><em>A shot of me in Portugal, not nearly as lean as my photo from Vietnam above, but not bad for someone who&#8217;s on the move. <a href="https://digitalnomadlifestyle.com/2022/09/19/lisbon-portugal-digital-nomad-guide/">Check out my digital nomad guide for Lisbon here.</a></em></p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img data-attachment-id="1928" data-permalink="https://digitalnomadlifestyle.com/2022/09/19/lisbon-portugal-digital-nomad-guide/img_3634/" data-orig-file="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2022/09/IMG_3634-3381997360-1663576121459.jpg?fit=3024%2C2951&amp;ssl=1" data-orig-size="3024,2951" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="IMG_3634" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2022/09/IMG_3634-3381997360-1663576121459.jpg?fit=300%2C293&amp;ssl=1" data-large-file="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2022/09/IMG_3634-3381997360-1663576121459.jpg?fit=750%2C732&amp;ssl=1" decoding="async" loading="lazy" src="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2022/09/IMG_3634-3381997360-1663576121459.jpg?resize=447%2C435&#038;ssl=1" alt="Nova Praia, Lisbon Portugal" class="wp-image-1928" width="447" height="435" srcset="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2022/09/IMG_3634-3381997360-1663576121459.jpg?resize=1024%2C999&amp;ssl=1 1024w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2022/09/IMG_3634-3381997360-1663576121459.jpg?resize=300%2C293&amp;ssl=1 300w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2022/09/IMG_3634-3381997360-1663576121459.jpg?resize=768%2C749&amp;ssl=1 768w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2022/09/IMG_3634-3381997360-1663576121459.jpg?resize=1536%2C1499&amp;ssl=1 1536w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2022/09/IMG_3634-3381997360-1663576121459.jpg?resize=2048%2C1999&amp;ssl=1 2048w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2022/09/IMG_3634-3381997360-1663576121459.jpg?resize=1200%2C1171&amp;ssl=1 1200w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2022/09/IMG_3634-3381997360-1663576121459.jpg?resize=1568%2C1530&amp;ssl=1 1568w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2022/09/IMG_3634-3381997360-1663576121459.jpg?w=2250&amp;ssl=1 2250w" sizes="(max-width: 447px) 100vw, 447px" data-recalc-dims="1" /></figure></div>


<p>This is a huge one, especially for people who <a href="https://digitalnomadlifestyle.com/2022/10/26/how-to-stay-healthy-while-traveling/">travel and want to stay fit.</a> Having a clear plan for my diet and exercise at the beginning of each day is absolutely essential for staying fit wherever I&#8217;m at.</p>



<p>For me this generally breaksdown into a couple of things</p>



<ol>
<li>My diet &#8211; what I&#8217;m going to eat that day</li>



<li>Stretching, band work &#8211; work to keep my body loose and mitigate injuries (or worsening existing injuries)</li>



<li>Exercise &#8211; what exercise I&#8217;m going to do that day</li>
</ol>



<h4 class="wp-block-heading">Career / Financial Work</h4>



<p class="has-text-align-center"><em>A shot of me in Rio De Janeiro, back when I was working office jobs, and far more focused on my career &amp; financial health, over my physical / mental health.</em></p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img data-attachment-id="2754" data-permalink="https://digitalnomadlifestyle.com/2023/04/28/daily-journalling-templates-travel/49172728_2434117006615811_1139392684041961472_n/" data-orig-file="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/49172728_2434117006615811_1139392684041961472_n.jpg?fit=960%2C539&amp;ssl=1" data-orig-size="960,539" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="49172728_2434117006615811_1139392684041961472_n" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/49172728_2434117006615811_1139392684041961472_n.jpg?fit=300%2C168&amp;ssl=1" data-large-file="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/49172728_2434117006615811_1139392684041961472_n.jpg?fit=750%2C421&amp;ssl=1" decoding="async" loading="lazy" src="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/49172728_2434117006615811_1139392684041961472_n.jpg?resize=566%2C317&#038;ssl=1" alt="Rio De Jainero Be" class="wp-image-2754" width="566" height="317" srcset="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/49172728_2434117006615811_1139392684041961472_n.jpg?w=960&amp;ssl=1 960w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/49172728_2434117006615811_1139392684041961472_n.jpg?resize=300%2C168&amp;ssl=1 300w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/49172728_2434117006615811_1139392684041961472_n.jpg?resize=768%2C431&amp;ssl=1 768w" sizes="(max-width: 566px) 100vw, 566px" data-recalc-dims="1" /></figure></div>


<p>For this section, ideally I want to find the 1 &#8211; 2 things I can do for my businesses that are going to have the biggest impact on my long-term business health. Here&#8217;s a podcast about figuring out your <a href="https://www.clinicmastery.com/concept-10-100-1000-per-hour-tasks-tasks-really-worth-investing/">${'$'}10, ${'$'}100 &amp; ${'$'}1,000 tasks</a> (I&#8217;m actually working through this week) to determine what those big tasks are.</p>



<p>The goal is to constantly be evaluating what I&#8217;m doing throughout the day for work. Is this something that&#8217;s in my <a href="https://aliceheiman.com/find-your-zone-of-genius/#:~:text=The%20Zone%20of%20Competence%3A%20Things,where%20you%20find%20your%20'flow.">zone of Genius</a> ( and worth ${'$'}1,000 an hour)?</p>



<p>If not, then I need to build out a process, and train someone else to do it. If it&#8217;s not important enough to train someone else to do it, then I need to really re-consider whether I should be doing it at all.</p>



<p class="has-text-align-center"><em>The vision board I created when I started my digital marketing business. I used to look at that photo of the labtop and the mountains in the background on a weekly basis dreaming about where I am today. I&#8217;m incredibly lucky, and I know that journalling has helped me immensely in getting here.</em></p>


<div class="wp-block-image">
<figure class="aligncenter size-large is-resized"><img data-attachment-id="2756" data-permalink="https://digitalnomadlifestyle.com/2023/04/28/daily-journalling-templates-travel/screenshot-2023-04-28-at-9-23-53-am/" data-orig-file="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/Screenshot-2023-04-28-at-9.23.53-AM.png?fit=1186%2C1090&amp;ssl=1" data-orig-size="1186,1090" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot-2023-04-28-at-9.23.53-AM" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/Screenshot-2023-04-28-at-9.23.53-AM.png?fit=300%2C276&amp;ssl=1" data-large-file="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/Screenshot-2023-04-28-at-9.23.53-AM.png?fit=750%2C689&amp;ssl=1" decoding="async" loading="lazy" src="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/Screenshot-2023-04-28-at-9.23.53-AM.png?resize=600%2C550&#038;ssl=1" alt="vision board example for men" class="wp-image-2756" width="600" height="550" srcset="https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/Screenshot-2023-04-28-at-9.23.53-AM.png?w=1186&amp;ssl=1 1186w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/Screenshot-2023-04-28-at-9.23.53-AM.png?resize=300%2C276&amp;ssl=1 300w, https://i0.wp.com/digitalnomadlifestyle.com/wp-content/uploads/2023/04/Screenshot-2023-04-28-at-9.23.53-AM.png?resize=1024%2C941&amp;ssl=1 1024w" sizes="(max-width: 600px) 100vw, 600px" data-recalc-dims="1" /></figure></div>


<h3 class="wp-block-heading" id="additional-notes">My Notes Section</h3>



<p>This is where I put my notes in for the day, what am I thinking about? What would I like to get off my chest? Etc.</p>



<p>I know people who will set a timer for 10 &#8211; 15 minutes to ensure that they get some free form writing out, I don&#8217;t do that but do think it&#8217;s a good idea for sure.</p>



<h2 class="wp-block-heading" id="quarterly-journalling">My Quarterly Journalling Practices</h2>



<p>So every 3 months I swap out my journal for a new one. I do this for a couple of reasons.</p>



<ol>
<li>This allows me to review my intentions, goals, visions for the future</li>



<li>I also use these journals as time capsules of the things I did. Where I can look back later on and remember where I was at in that quarter, what I was doing, etc.</li>
</ol>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Journaling Tips For Travelers" width="750" height="422" src="https://www.youtube.com/embed/aZBgRaAwQFc?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
</div><figcaption class="wp-element-caption">Showing how I use my journals as time capsules of my trips</figcaption></figure>



<p>Here&#8217;s the list of my quarterly journalling practices</p>



<ol>
<li>Listing out healthier ways I can get my main needs met
<ul>
<li><strong>Validation</strong></li>



<li><strong>Comfort</strong></li>



<li><strong>Connection</strong></li>



<li><strong>Novelty</strong> </li>
</ul>
</li>



<li><strong>My Intentions</strong> &#8211; <em>How do I want to live my daily life</em>


<ul>
<li>I break these down into the same 3 categories I use in my daily journal, Mental / Spiritual, Physical, &amp; Career / Financial</li>



<li>I limit this to 10 items maximum per category, and list them out in order of how important they are. This helps me huge in prioritizing my daily goals and what I should be doing day to day.</li>
</ul>



<ul>
<li>This varies a lot from my bucket list items, and where I want to be at 40, because these are things I want to do day to day.</li>
</ul>
</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h4 class="wp-block-heading has-text-align-center"><strong>A Couple Articles About Goal Setting<br></strong><br><a href="https://digitalnomadlifestyle.com/2022/12/01/goal-setting-how-dreams-change/">Goal Setting &amp; How Goals Change</a></h4>



<h4 class="wp-block-heading has-text-align-center"><a href="https://digitalnomadlifestyle.com/2022/05/15/why-i-dont-focus-on-goals/">Why I Don&#8217;t Focus On Goal Setting Anymore</a></h4>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<ol>
<li><strong>My Bucket List</strong> &#8211; List of things I want to do before my 40th Birthday.
<ul>
<li>I really try to push myself to list out all of the things I&#8217;d like to experience that bring me the most excitement, even if they seem far-fetched.</li>



<li>Reviewing and re-writing these quarterly is huge in keeping me motivated!</li>
</ul>
</li>



<li><strong>Where Do I Want To Be At 40?</strong> Listing out how I want my life to look like at 40, broken down into 4 categories
<ul>
<li>Mental / Spiritual</li>



<li>Physical</li>



<li>Career / Financial</li>



<li>Misc. / Lifestyle</li>



<li>This is very similar to a <em>BHAG</em> &#8211; a Big Hairy Audacious goal, but I list out the year I want to have these goals come true. This makes the goal feel much more tangible.</li>
</ul>
</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="has-text-align-center wp-block-heading"> <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f64b-200d-2640-fe0f.png" alt="🙋‍♀️" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Want to stay up to date on my journey?</h2>



<h2 class="has-text-align-center wp-block-heading">Or &#8211; Looking For Regular Digital Nomad Content &amp; Inspiration? <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f64b-200d-2640-fe0f.png" alt="🙋‍♀️" class="wp-smiley" style="height: 1em; max-height: 1em;" /></h2>



<h2 class="has-text-align-center wp-block-heading"><a href="https://www.instagram.com/officialdigitalnomadlifestyle/">Follow Me On Instagram</a> &#8211; @officialdigitalnomadlifestyle </h2>
<p>The post <a rel="nofollow" href="https://digitalnomadlifestyle.com/2023/04/28/daily-journalling-templates-travel/">Daily Journalling, Goal &#038; Intention Setting</a> appeared first on <a rel="nofollow" href="https://digitalnomadlifestyle.com">Digital Nomad Lifestyle</a>.</p>
""")
}

java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 0
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
at java.base/java.util.Objects.checkIndex(Objects.java:372)
at java.base/java.util.ArrayList.get(ArrayList.java:459)
at com.mohamedrejeb.ksoup.html.parser.KsoupHtmlParser.closeCurrentTag(KsoupHtmlParser.kt:187)
at com.mohamedrejeb.ksoup.html.parser.KsoupHtmlParser.onSelfClosingTag(KsoupHtmlParser.kt:172)
at com.mohamedrejeb.ksoup.html.tokenizer.KsoupTokenizer.stateInSelfClosingTag(KsoupTokenizer.kt:354)
at com.mohamedrejeb.ksoup.html.tokenizer.KsoupTokenizer.parse(KsoupTokenizer.kt:613)
at com.mohamedrejeb.ksoup.html.tokenizer.KsoupTokenizer.write(KsoupTokenizer.kt:58)
at com.mohamedrejeb.ksoup.html.parser.KsoupHtmlParser.write(KsoupHtmlParser.kt:378)
at com.mohamedrejeb.ksoup.html.parser.KsoupHtmlParser.end(KsoupHtmlParser.kt:394)
at com.mohamedrejeb.ksoup.html.parser.KsoupHtmlParser.parseComplete(KsoupHtmlParser.kt:335)

Note that this is a real case scenario when trying to parse the content description of a Feed in order to try to look for images: https://digitalnomadlifestyle.com/feed/

decodeHtml4 & decodeHtml5 in one step

decodeHtml5 isn't a set which also contains the decodeHtml4 entities. I'd like to invoke both. I know that I can call them one after another however, but I'm guessing performance wise a single call would be better. Since it'd only need to loop once instead of twice over the string. Also NumericEntityDecoder() is used twice which is unnecessary.

Esentially, I want an aggregator like this:

AggregateTranslator(
    LookupTranslator(EntityMaps.HTML4Decode),
    LookupTranslator(EntityMaps.HTML5Decode),
    NumericEntityDecoder(),
)

Side note: I also found decodeHtml confusing as at first I thought this is decode4+5 but it's just 5, in which case, I'd go for removing that method to make the API smaller & conciser.

Add new module for scrapping websites with Ktor

  • Make a new module to more advanced use cases to keep the :ksoup-html module as lightweight as possible
  • Support parsing data from websites
  • Add new methods for make web scrapping easier (eq: get elements by tag id or by class name...)

Issues with & symbol

Hi, how can I detect a character reference(&amp and etc). If i try to get it with onText Ksoup gives only & symbol.

Exception when parsing HTML without title tag

I'm adding a HTML snippet to the parser, by manually surrounding it with <html><body>$content</body></html>. This lead to the exception listed below:

java.util.NoSuchElementException: List is empty.
	at kotlin.collections.CollectionsKt___CollectionsKt.last(_Collections.kt:418)
	at com.mohamedrejeb.ksoup.html.parser.KsoupHtmlParser.onSelfClosingTag(KsoupHtmlParser.kt:170)
	at com.mohamedrejeb.ksoup.html.tokenizer.KsoupTokenizer.stateInSelfClosingTag(KsoupTokenizer.kt:354)
	at com.mohamedrejeb.ksoup.html.tokenizer.KsoupTokenizer.parse(KsoupTokenizer.kt:613)
	at com.mohamedrejeb.ksoup.html.tokenizer.KsoupTokenizer.write(KsoupTokenizer.kt:58)
	at com.mohamedrejeb.ksoup.html.parser.KsoupHtmlParser.write(KsoupHtmlParser.kt:378)

Changing the input to <html><head><title>etc</title></head><body>$content</body></html> is a workaround. I'm using version 0.1.3.

Missing Prougard rule

Usage of the library causes app to crash with Android release builds because R8 removes unused classes or methods from the Ksoup library. Specifically, Builder#onOpenTag is stripped out, causing a crash when only Builder#onCloseTag is called in the app.

Here's a simplified example of how the library is used in the app:

val handler = KsoupHtmlHandler
  .Builder()
  .onOpenTag { name, attributes, _ -> Logger.d { "tag opening name: $name" } }
  .onCloseTag { name, _ -> Logger.d { "tag closing name: $name" } }
  .build()
  
val parser = KsoupHtmlParser(handler)
try {
  val html = "<p> Welcome to my home page. </p>"
  parser.write(html)
} finally {
  parser.end()
}  

Adding the following ProGuard rule resolves the issue:

-keep class com.mohamedrejeb.ksoup.html.parser.KsoupHtmlHandler.Builder**, * { *; }

Ideally, this rule could be shipped with the library to avoid manual configuration by consumers?

I'm unsure of the best way forward, but I believe this issue warrants further investigation.

P.S. Thanks for the library, saved me a ton of time parsing html tags in a KMM project

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.