Walking Trip …

Walking Trip

Walking Trip

Offenbach's Suite ... Warts 'n All

Offenbach's Suite ... Warts 'n All

 📅  

If this was interesting you may be interested in this too.

Posted in Photography, Trips | Tagged , , | 34 Comments

Landing Page Web Inspector iPhone CSS Styling Tutorial

Landing Page Web Inspector iPhone CSS Styling Tutorial

Landing Page Web Inspector iPhone CSS Styling Tutorial

We’ve put up with a Landing Page annoyance regarding iPhone Portrait viewing for some time now, but today we’ve bitten the bullet and attended to the issue whereby the last “g” in RJM Programming butted up to the right hand side of the Portrait screen annoyingly. They say “pixel perfect” and today’s work is a bit like that, further to other web inspector work helping the Landing Page talked about at Landing Page Web Inspector CSS Styling Tutorial.

Today, we make use of the fact that CSS can be dynamically changed in the arrangements of most webpages just by adding <style> CSS styling </style> into the innerHTML property of a suitable HTML element.

We also found the CSS clause …

!important

… impotent, on occasions, helping, and so we went around with Javascript DOM “undoing” a className scenario, something we cannot remember ever undertaking, but not so strange given it is only …

  1. iPhone device width
  2. Portrait

… scenarios we are talking about here. That “unclassing” leaves the door open to ensuring our chosen 62px font-size CSS property holds sway, for these scenarios. In doing the job, it was our default just to break the …


RJM Programming

… text at the space character, and that “ever so mild” scrunching up of content helped, but there are a myriad of ways to going about this job, tabularized below …

Idea Javascript DOM
Default
document.getElementById('topspan').innerHTML=document.getElementById('topspan').innerHTML.replace('RJM Programming', 'RJM</h1><h1 style=font-size:62px;>Programming').replace(/\<\/hJUNK1/g, '</h2');
Border
setTimeout(function(){ document.getElementById('toph1').className=document.getElementById('toph1').className.replace('jumbo', 'jumXbo');
document.getElementById('laststyle').innerHTML+='<style> h1 { font-size: 62px !important; } </style>';
document.getElementById('laststyle').innerHTML+='<style> h1 { outline-right: 6px solid transparent; } </style>';
}, 200);
Classname
setTimeout(function(){ document.getElementById('toph1').className=document.getElementById('toph1').className.replace('jumbo', 'jumXbo');
document.getElementById('laststyle').innerHTML+='<style> h1 { font-size: 62px !important; } </style>';
}, 200);
Margin
setTimeout(function(){ document.getElementById('toph1').className=document.getElementById('toph1').className.replace('jumbo', 'jumXbo');
document.getElementById('laststyle').innerHTML+='<style> h1 { font-size: 62px !important; } </style>';
document.getElementById('laststyle').innerHTML+='<style> h1 { padding-right: 6px; } </style>';
}, 200);
Font
setTimeout(function(){ document.getElementById('toph1').className=document.getElementById('toph1').className.replace('jumbo', 'jumXbo');
document.getElementById('laststyle').innerHTML+='<style> h1 { font-size: 62px !important; } </style>';
}, 200);
After
setTimeout(function(){ document.getElementById('toph1').className=document.getElementById('toph1').className.replace('jumbo', 'jumXbo');
document.getElementById('laststyle').innerHTML+='<style> h1 { font-size: 62px !important; } </style>';
document.getElementById('laststyle').innerHTML+="<style> h1:after { content: ' ' !important; } </style>";
}, 200);
Wording
setTimeout(function(){ document.getElementById('toph1').className=document.getElementById('toph1').className.replace('jumbo', 'jumXbo');
document.getElementById('laststyle').innerHTML+='<style> h1 { font-size: 62px !important; } </style>';
document.getElementById('toph1').innerHTML+=" ";
}, 200);
Overflow
setTimeout(function(){ document.getElementById('toph1').className=document.getElementById('toph1').className.replace('jumbo', 'jumXbo');
document.getElementById('laststyle').innerHTML+='<style> h1 { font-size: 62px !important; } </style>';
document.getElementById('topspan').style.width='' + eval(0 + eval('' + document.documentElement.clientWidth)) + 'px';
document.getElementById('topspan').style.wordWrap='keep-all';
}, 200);
Was

… in a changed index.php RJM Programming Landing Page.


Previous relevant Landing Page Web Inspector CSS Styling Tutorial is shown below.

Landing Page Web Inspector CSS Styling Tutorial

Landing Page Web Inspector CSS Styling Tutorial

Are you a member of the IBORT? If not, would you like to become a member? Anyone, anyone? Hang on, Isaac, can you please “use your words” in front of the class, please …

What does IBORT stand for?

Okay, class … over to you

Well, okay Sandra, yes, we understand “World Peace” might work … but anyone else?

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

You all give up?!

International Board of Registered Tweakers
(no Registered Tweakers were harmed in the making of this infomercial)

Yes, you can tweak webpages in the morning or afternoon, and for simple styling changes we recommend …

  1. getting the relevant webpage showing in your favoured web browser on a non-mobile platform …
  2. inspect that webpage via that web browser’s Web Inspector … for Google Chrome on macOS we went …

    View -> Developer -> Developer Tools -> "Elements" tab

  3. the “before your eyes, dynamically” approach being to zero in on web element style=”[CSS styling]” parts and, “tweak away” …
  4. the results immediate and further tweakable, until you are happy … then …
  5. think what can be done to directly, or indirectly (eg. “client pre-emptive iframe” action) to simulate this change back at the relevant code (in our RJM Programming Landing Page case some PHP in our Apache web server’s Document Root folder called “index.php”) to simulate what you were happy with back at your Web Inspector session (ie. until this, your changes are “Ephemeral”) …
  6. you upload into place to turn a “tweak” into some “tweak realia”

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

Posted in eLearning, iOS, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

Window Object Screen Member Variables Overlay Tutorial

Window Object Screen Member Variables Overlay Tutorial

Window Object Screen Member Variables Overlay Tutorial

Onto yesterday’s Window Object Screen Member Variables Tutorial we nuance …

  • “overlay”

    if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
    document.body.innerHTML+='<span id=vertborder data-class="hseparator" style="color:transparent;position:absolute;left:91%;top:50%;z-index:99;transform:rotate(90deg);">document.documentElement.clientHeight=' + document.documentElement.clientHeight + '</span>';
    } else {
    document.body.innerHTML+='<span id=vertborder data-class="hseparator" style="color:transparent;position:absolute;left:94.25%;top:50%;z-index:99;transform:rotate(90deg);">document.documentElement.clientHeight=' + document.documentElement.clientHeight + '</span>';
    }

    and “flex”

    <style>
    .hseparator { /* thanks to https://stackoverflow.com/questions/2812770/add-centered-text-to-the-middle-of-a-horizontal-rule */
    display: flex;
    align-items: center;
    text-align: center;
    }

    .hseparator::before,
    .hseparator::after {
    content: '';
    flex: 1;
    border-bottom: 1px solid #000;
    }

    .hseparator:not(:empty)::before {
    margin-right: .25em;
    }

    .hseparator:not(:empty)::after {
    margin-left: .25em;
    }
    </style>

    styles of document.documentElement.clientHeight and document.documentElement.clientWidth respective means of indicating the dimension for the user’s screen scenario …
  • for mobile display a screen orientation string ( based on the “faux” <img alt=”#screen.orientation” id=mynoimg style=’display:none;’></img> )

    var ismob=false;
    if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
    ismob=true;
    }
    var thisso=(('' + ismob) == 'false' ? '' : ('' + (screen.msOrientation || screen.mozOrientation || (screen.orientation || {}).type))); //"portrait";

    function omo(areao) {
    if (areao.alt == '#screen.orientation') {
    conceptis=('' + (screen.msOrientation || screen.mozOrientation || (screen.orientation || {}).type));
    //alert(conceptis);
    console.log(tdr(areao.alt.replace(/^\#/g,'') + '=' + conceptis));
    } else if (areao.alt == '#screen') {
    console.log(tdr('screen.width,screen.height=' + screen.width + ',' + screen.height));
    } else {
    conceptis='' + eval(areao.alt.replace(/^\#/g,''));
    console.log(tdr(areao.alt.replace(/^\#/g,'') + '=' + conceptis));
    }
    }

    if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
    if (8 == 8) {
    setInterval(function(){ omo(document.getElementById('mynoimg')); }, 5000);
    } else {
    // Listen for the deviceorientation event and handle the raw data
    window.addEventListener('deviceorientation', function(eventData) {
    omo(document.getElementById('mynoimg'));
    });
    }
    }

  • improve text readability

… in the changed “second draft” window_dom_concept.html web application below.


Previous relevant Window Object Screen Member Variables Tutorial is shown below.

Window Object Screen Member Variables Tutorial

Window Object Screen Member Variables Tutorial

We stumbled upon an excellent diagram image to explain some of the window object member variables available to Javascript DOM and describing the various dimensions of device screen parts at https://moo-you.tistory.com/882

… thanks. Knowing that, we harnessed the great mobilefish generated HTML map element, thanks, to write a “first draft” window_dom_concept.html web application to help the user explore these window object member variables for themselves using …

We hope it is of some interest!

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , | Leave a comment

Window Object Screen Member Variables Tutorial

Window Object Screen Member Variables Tutorial

Window Object Screen Member Variables Tutorial

We stumbled upon an excellent diagram image to explain some of the window object member variables available to Javascript DOM and describing the various dimensions of device screen parts at https://moo-you.tistory.com/882

… thanks. Knowing that, we harnessed the great mobilefish generated HTML map element, thanks, to write a “first draft” window_dom_concept.html web application to help the user explore these window object member variables for themselves using …

We hope it is of some interest!

If this was interesting you may be interested in this too.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , | Leave a comment

Animated GIF versus PDF Presentation Considerations Tutorial

Animated GIF versus PDF Presentation Considerations Tutorial

Animated GIF versus PDF Presentation Considerations Tutorial

The RJM Programming web server is a Linux one, which means, in terms of it’s hard disk, file resource allocation limits happen regarding both …

  • disk storage in bytes (affected by how large your files are/get)
  • number of files in total regarding the system’s inode count limit (affected by how many files there are/get to)

When it comes to our blog posting tutorial image(s) around here, it often pans out that a concept cannot be fully explained or embellished by any one image.

In “the old days” we used to Javascript navigate through a “faux” animation showing the presentation via this methodology. That was okay for a while until we realized the impact on our Linux system inode count limit, so we modified that to a “unzip on request” model which rezipped after some time using PHP, which at that time fully supported it’s own “zip” functions. In PHP 8 it no longer does (and for these, still existing, scenarios we’ve resorted to a less functional, but working, PHP calls Linux operating system “zip/unzip” via exec approach).

Before any PHP of an 8 version ilk (which we jumped to from a 5) we started down the road trying presentations in one of two other ways. In order of how often we started …

  1. wrapping up many images into single “inhouse created” animated GIF … or …
  2. wrapping up many images into single PDF file using as our preferred method macOS Preview -> make changes -> File -> Print… -> manage any rotation or scaling issues -> Save as PDF…

… methodologies. Below is what we see as the Pros and Cons of this choice …

Criteria Animated GIF PDF
Output format Pro – img easier than iframe to make cross browser and cross platform friendly
Simplicity Con – scrolling required
Confusion Con – some users may be confused by delay too little or too much and when presentation starts/stops
Analysis Pro – user has control to fully take in the information at their pace
Gathering slides Con – our inhouse animated GIF creator can order on the fly via user nouse but takes a lot longer to gather slides Pro – really easy off macOS Finder multiple highlighting -> Open With… -> Preview (and from there slides can be reordered reasonably straightforwardly)
Annotations Pro – Speech Bubbles can often be really useful

… and the making of CSS Web Application External Javascript Programmatical Updates Tutorial recently gave us pause for thought. We felt Speech Bubbles were necessary, but did not want the bother of a PDF presentation, with it’s HTML iframe cross browser issues, and so, on this occasion we …

  1. gathered slides on macOS to Preview
  2. reordered pretty easily
  3. added lots of Speech Bubbles (at least one per slide) to better explain what we meant regarding the presentation on a slide by slide basis
  4. File -> Print… -> rotated to landscape view -> Save as PDF… css_webapps_peer_more.pdf

… and then we could have used our inhouse PDF to Image(s) approach, but at that web application’s heart, anyway, is the ImageMagick magic operating system call of the ilk of the command …


convert -delay 4000 css_webapps_peer_more.pdf css_webapps_peer_more.gif

… macOS one we plumped for to end up with CSS Web Application External Javascript Programmatical Updates Tutorial‘s animated GIF presentation featuring Preview PDF created Speech Bubbles … win, win!

If this was interesting you may be interested in this too.

Posted in Animation, eLearning, Event-Driven Programming, Operating System, Tutorials | Tagged , , , , , , , , , , , , , , , , , | Leave a comment

Messages iOS App Photo Attachment Options Tutorial

Messages iOS App Photo Attachment Options Tutorial

Messages iOS App Photo Attachment Options Tutorial

We had a …

Yeah, yeah, yeah. We know we should know that!

… moment yesterday, communicating via SMS on our iPhone.

The solution to our pickle ended up being that, amongst …

1
On iPhone, in Messages app, in an SMS containing an image, one of the options on holding your finger over that image under (the tapping of the) "More..." option tapping the right pointing arrow icon down the bottom opena a new SMS with that image as an "attachment" (if you will)
2
On iPhone, in Messages app, in an SMS containing an image, one of the options on holding your finger over that image under (the tapping of the) "Save" option allows for the copying of image to Photos app

… ideas the second one was of great use in our pickle. Which begs the question …

Tell us more about your pickle? And forget any jokes regarding gherkins, please!!!

Well, you twisted my gherkin … sorrrrryarm!

Okay, was trying to describe a car tyre to a guy who knew a lot about tyres, but wasn’t at the car during the initial Phone app (on iPhone) conversation I was having with the guy.

Got an SMS from my partner of a photo of the tyre in question from another iPhone Messages app via it’s Camera app. Meanwhile the guy can’t identify the tyre me telling him of the car make and model number and year, so he wants to see photos of the tyre in an SMS, and so he gives me his SMS number (and I don’t have a pen … Murphy’s Law).

Anyway, I was not aware of “idea 1” above, alas, because I could have shaped to send the photo(s) there and then on the iPhone via the Messages app still talking to the guy. But I panicked, and in the panic, forgot three of the numbers (but we digress). Anyway, eventually we got that aspect sorted and was in an SMS message wanting to include that image from the other SMS and it was that “idea 2” that got us out of our pickle because back at the new SMS the + icon has an option to attach an image via the Photos app (and to take the image via the Camera app, of course, too).

Any of this familiar?! We know we’re lacking in the nuances of SMS communication, but was wondering if these revelations are helpful to any iPhone SMS users out there?!

If this was interesting you may be interested in this too.

Posted in eLearning, iOS, Tutorials | Tagged , , , , , , , , , , , , , , , | Leave a comment

CSS Web Application External Javascript Programmatical Updates Tutorial

CSS Web Application External Javascript Programmatical Updates Tutorial

CSS Web Application External Javascript Programmatical Updates Tutorial

Two jobs today, moving on from yesterday’s CSS Web Application External Javascript Peer to Peer Tutorial

  1. allow any random backdrop background image, specified by the user, have it’s content be retained sharing with any email recipient shared with, just concerning the changed fifth draft CSS Backdrop Filter web application also shown below
  2. arrange it that the software updates itself without manual intervention adding to the array up the top of the external Javascript

That second “peer to peer” ambition we’ve attempted in the past, and needed PHP, and for a hour today we deluded ourselves we could achieve “programmatical updates” just with …

  • external Javascript css_webapps_peer.js changes … with …
  • window.localStorage (like HTTP cookie) usage … but those two only did the full job we were after regarding the “first instigator”, not the rest of users ever calling that web application, because non-server ideas cannot “programmatically update” the array in the external Javascript code … whereas …
  • introducing “self contained” changes in some PHP middle_interest.php within the same web server folder …

… completed the job whereby uploaded new web applications to the RJM Programming domain should trigger “programmatical updates” to that topmost dropdown of “the peerage” of web applications. The understanding goes …

  • “the peerage” new member is probably cloned off an older member … meaning …
  • “the peerage” new member calls the same external Javascript (introduced yesterday into the mix) … meaning …
  • anyone’s first call of “the peerage” new member (ie. in all likelihood, the programmer creating it) triggers two things …
    1. an updated window.localStorage member (which can contribute to anyone’s topmost dropdown should it be in the correct format) … and for this “first instigator” (only, because of what it does) …
    2. call of helper PHP with that “self contained” server code …
      <?php

      // http://www.rjmprogramming.com.au/HTMLCSS/middle_interest.php?htmlparity=&jsname=./css_webapps_peer.js&with=document.URL.split('?')[0].split('#')[0]&inthesenseof=mywasel
      if (isset($_GET['htmlparity']) && isset($_GET['with']) && isset($_GET['inthesenseof']) && isset($_GET['jsname'])) {
      if (str_replace('+',' ',urldecode($_GET['inthesenseof'])) != 'mywasel' && strpos(str_replace('+',' ',urldecode($_GET['jsname'])), '/css_webapps_peer.js') !== false) {
      exit;
      } else if (strpos(str_replace('+',' ',urldecode($_GET['jsname'])), '/css_webapps_peer.js') === false) {
      exit;
      }
      $jscont='';
      $withcont=file_get_contents(str_replace('https:','http:',str_replace('+',' ',urldecode($_GET['jsname']))));
      if ($withcont != '') {
      $jscont=$withcont;
      $wcont=file_get_contents('./' . basename(str_replace('https:','http:',str_replace('+',' ',urldecode($_GET['with'])))));
      if ($withcont != '') {
      $wewanttwo=explode('./' . basename(str_replace('+',' ',urldecode($_GET['with']))), $withcont);
      if (sizeof($wewanttwo) == 1) {
      $wewantthree=explode(str_replace('+',' ',urldecode($_GET['inthesenseof'])), $wcont);
      if (sizeof($wewantthree) > 1) {
      $jscont=str_replace('"];', '","' . './' . basename(str_replace('+',' ',urldecode($_GET['with']))) . '"];', $jscont);
      file_put_contents('./' . basename(str_replace('+',' ',urldecode($_GET['jsname']))), $jscont);
      }
      }
      }
      }
      exit;
      }

      ?>
      … which might add to the external Javascript top array on (web server) disk

    via (the near to document.body onload event function)

    var walist=["./background_position_various.html","./apply_a_mask.html","./backdrop_filter.html"];

    function addtodropdown() {
    var inbv=0, jnbv=0, apptitleis='', ocdone=false, wlsarr=[], iwl=0;
    var wasohis='';
    var appwordsare=[];
    if (document.getElementById('mywasel')) {
    if (('' + window.localStorage.getItem('css_webapps_peer_more_options')).toLowerCase().replace(/^undefined/g,'').replace(/^null/g,'') != '') {
    wlsopts=yourdecodeURIComponent('' + window.localStorage.getItem('css_webapps_peer_more_options'));
    wlsarr=wlsopts.split(',');
    for (iwl=0; iwl<wlsarr.length; iwl++) {
    if (walist.indexOf('./' + wlsarr[iwl].split('/')[eval(-1 + wlsarr[iwl].split('/').length)].split('?')[0].split('#')[0]) == -1) {
    walist.push('./' + wlsarr[iwl].split('/')[eval(-1 + wlsarr[iwl].split('/').length)].split('?')[0].split('#')[0]);
    }
    }
    }
    if (walist.indexOf('./' + document.URL.split('/')[eval(-1 + document.URL.split('/').length)].split('?')[0].split('#')[0]) == -1) {
    walist.push('./' + document.URL.split('/')[eval(-1 + document.URL.split('/').length)].split('?')[0].split('#')[0]);
    if (wlsopts == '') {
    window.localStorage.setItem('css_webapps_peer_more_options', encodeURIComponent('./' + document.URL.split('/')[eval(-1 + document.URL.split('/').length)].split('?')[0].split('#')[0] + ''));
    wlsopts='./' + document.URL.split('/')[eval(-1 + document.URL.split('/').length)].split('?')[0].split('#')[0] + '';
    } else {
    window.localStorage.removeItem('css_webapps_peer_more_options');
    window.localStorage.setItem('css_webapps_peer_more_options', encodeURIComponent(wlsopts + ',./' + document.URL.split('/')[eval(-1 + document.URL.split('/').length)].split('?')[0].split('#')[0] + ''));
    wlsopts+=',./' + document.URL.split('/')[eval(-1 + document.URL.split('/').length)].split('?')[0].split('#')[0] + '';
    }
    if (document.getElementById('ifbot')) {
    if (('' + document.getElementById('ifbot').src).indexOf('/About_Us.htm') != -1) {
    document.getElementById('ifbot').src='/HTMLCSS/middle_interest.php?htmlparity=&jsname=' + encodeURIComponent('./css_webapps_peer.js') + '&with=' + encodeURIComponent(document.URL.split('?')[0].split('#')[0]) + '&inthesenseof=mywasel';
    }
    }
    }

    wasohis=document.getElementById('mywasel').outerHTML;
    for (inbv=0; inbv<walist.length; inbv++) {
    if (wasohis.indexOf(walist[inbv]) == -1) {
    apptitleis='';
    appwordsare=walist[inbv].split('/')[eval(-1 + walist[inbv].split('/').length)].split('.')[0].split('_');
    for (jnbv=0; jnbv<appwordsare.length; jnbv++) {
    if (eval('' + appwordsare[jnbv].length) <= 3) {
    apptitleis+=' ' + appwordsare[jnbv].toLowerCase();
    } else {
    apptitleis+=' ' + appwordsare[jnbv].substring(0,1).toUpperCase() + appwordsare[jnbv].substring(1).toLowerCase();
    }
    }
    if (apptitleis != '') {
    document.getElementById('mywasel').innerHTML+='<option value="' + walist[inbv] + '">' + apptitleis + '</option>';
    }
    }
    if (!ocdone && wasohis.indexOf(' onchange=') == -1) {
    ocdone=true;
    document.getElementById('mywasel').onchange=function(event) { if (event.target.value.trim() != '') { location.href=event.target.value; } };
    } else {
    ocdone=true;
    }
    }
    }
    // blah blah blah
    }

    … meaning non “first instigator” users need neither helper above


Previous relevant CSS Web Application External Javascript Peer to Peer Tutorial is shown below.

CSS Web Application External Javascript Peer to Peer Tutorial

CSS Web Application External Javascript Peer to Peer Tutorial

We tackle a few more issues onto yesterday’s CSS Web Application Highlighted Text Tutorial with …

  • peer to peer linking of these 3 (so far) CSS referencing web applications via a new header element dropdown element
  • some better email functionality when the web application is hosted such as it is with the “shown below” links in this blog posting
  • allow a change of background image to use for the Backdrop Filter web application

The first two used for their work the code of a new css_webapps_peer.js external Javascript interfacing with …


Previous relevant CSS Web Application Highlighted Text Tutorial is shown below.

CSS Web Application Highlighted Text Tutorial

CSS Web Application Highlighted Text Tutorial

You may have been around reading this blog to recall Sentence Text Word Underlining Primer Tutorial‘s discussions regarding the text data talents of HTML element type textarea up against div and the resultant table reflecting our views on this …

Text Talents of HTML Elements
Textarea … versus … Div
And CSS 3D Transformation Matrix Making Of Interactive Integration Tutorial set out how we see the pros and cons as …
Text Functionality Issue HTML Element Type Strength Weakness (where a “Yes” is like … “Oh No!”)
Display Monocolour Text Textarea Yes
Div Yes
Display Editable Text Textarea Yes
Div Yes
Display Multicolour Text Textarea Yes
Div Yes

… and it’s assertion that regarding Display Multicolour Text the use of textarea elements were not suitable. Well, today, we do not resile from that view, when you consider a textarea element on it’s own, but what if it gets “overlay” type of help from div nesting span elements (and we have “reverse corollaries” here with SVG tspan element usage in SVG Tspan Element Primer Tutorial) with background colour and transparent text, leading to capabilities where textarea text of relevance can be highlighted.

Sounds good?! Yes, but it must be said we could have just replaced the textarea elements (within our CSS Themed suit of web applications of recent times, talked about with yesterday’s CSS Backdrop Filter Recursive Iframe Tutorial) with div ones where contenteditable=true could still allow for interactivity, but for the reasons …

  • we wanted to see if highlighting text within a textarea could be achieved … Spoiler Alert: yes, it’s possible … as well as
  • textarea elements have a great resizing “native” functionality
  • textarea elements feel far more “the go” when asking for user interactive entry data that can contain linefeeds
  • over time we find more and more use for the textarea attributes value and innerHTML as separately useful dual ways of populating the element, especially in the scenario with text data where the latter is useful to initiate with text data containing < and > which gets mapped to &lt; and &gt; respectively once the code looks at that textarea‘s value attribute … Cute, huh?! In fairness, though div contenteditable=true also have interesting interplay with innerHTML and innerText attributes going on in this respect too.

… we’re carrying on with textarea element interactive entry usage with this current suite of CSS based web applications.

Here’s the new Javascript function crucial to making this possible …


function divoverlayclone(ovid, indefst) {
var tih='', taih=document.getElementById('divhost').innerHTML, nextih='', tbit='', huhs=[], ihuh=0, mss='', ahh=[], ione=1, ihh=0;
var tarectis=document.getElementById('taidea').getBoundingClientRect();
if (ovid == '') { ovid='doverlay'; } else {
mss=ovid.replace('doverlay','');
for (var iou=0; iou<eval('' + mss); iou++) {
ahh.push('');
}
}
var defclass=(' ' + mss).slice(-1).trim();
for (var itih=taih.indexOf('<'); itih<taih.length; itih++) {
if (taih.substring(itih).substring(0,1) == String.fromCharCode(10)) {
tih+='<br>';
} else if (taih.substring(itih).substring(0,1) == '<') {
tih+='<';
} else if (taih.substring(itih).substring(0,1) == '>') {
tih+='>';
} else {
tih+=taih.substring(itih).substring(0,1);
}
}
document.getElementById(ovid).style.position='absolute';
document.getElementById(ovid).style.top='' + tarectis.top + 'px';
document.getElementById(ovid).style.left='' + tarectis.left + 'px';
document.getElementById(ovid).style.width='' + tarectis.width + 'px';
document.getElementById(ovid).style.height='' + tarectis.height + 'px';
document.getElementById(ovid).style.fontSize = window.getComputedStyle(document.getElementById('taidea'),null).fontSize || document.getElementById('taidea').style.fontSize || document.getElementById('taidea').currentStyle.getCurrentProperty('font-size');
if (indefst.trim() != '') {
//alert('0:' + indefst);
if (document.getElementById('divhost').innerHTML.indexOf(indefst.replace(':',': ')) != -1) {
//alert('00:' + indefst);
if (tih.indexOf(indefst.replace(':',': ') + '">') != -1) {
document.getElementById(ovid).innerHTML=tih.replace(indefst.replace(':',': ') + '">', '<span id=myspan' + mss + ' class=highlight' + (' ' + mss).slice(-1).trim() + ' title="' + indefst.replace(':',': ') + '">' + indefst.replace(':',': ') + '</span>">');
} else {
document.getElementById(ovid).innerHTML=tih.replace(indefst.replace(':',': '), '<span id=myspan' + mss + ' class=highlight' + (' ' + mss).slice(-1).trim() + ' title="' + indefst.replace(':',': ') + '">' + indefst.replace(':',': ') + '</span>');
}
} else if (document.getElementById('divhost').innerHTML.indexOf(indefst) != -1) {
//alert('000:' + indefst);
if (tih.indexOf(indefst + '">') != -1) {
document.getElementById(ovid).innerHTML=tih.replace(indefst + '">', '<span id=myspan' + mss + ' class=highlight' + (' ' + mss).slice(-1).trim() + ' title="' + indefst + '">' + indefst + '</span>">');
} else {
document.getElementById(ovid).innerHTML=tih.replace(indefst, '<span id=myspan' + mss + ' class=highlight' + (' ' + mss).slice(-1).trim() + ' title="' + indefst + '">' + indefst + '</span>');
}
} else {
return '';
}
} else {
//alert(defst);
if (defst.indexOf(';') == -1) {
huhs=defst.split(' ');
//alert('2:' + huhs[0]);
for (ihuh=0; ihuh<huhs.length; ihuh++) {
if (document.getElementById('mysel').innerHTML.indexOf(' value="' + huhs[ihuh] + '">') != -1) {
//alert('3:' + huhs[0]);
tbit+=document.getElementById('mysel').innerHTML.split(' value="' + huhs[ihuh] + '">')[1].split('<')[0];
ahh.push('doverlay' + ione + '~' + document.getElementById('mysel').innerHTML.split(' value="' + huhs[ihuh] + '">')[1].split('<')[0]);
ione++;
}
}
defclass='' + ahh.length;
//alert('defclass=' + defclass);
document.getElementById(ovid).innerHTML=tih.replace(defst, '<span id=myspan' + mss + ' class=highlight' + defclass + ' title="' + tbit + '">' + defst + '</span>');
} else if (document.getElementById('mysel').innerHTML.indexOf(' value="' + defst + '">') != -1) {
if (eval('' + tih.split(defst).length) > 2) {
ahh.push('doverlay' + ione + '~' + document.getElementById('mysel').innerHTML.split(' value="' + defst + '">')[1].split('<')[0]);
ione++;
defclass='' + ahh.length;
}
document.getElementById(ovid).innerHTML=tih.replace(defst, '<span id=myspan' + mss + ' class=highlight' + defclass + ' title="' + document.getElementById('mysel').innerHTML.split(' value="' + defst + '">')[1].split('<')[0] + '">' + defst + '</span>');
} else {
//alert(defst + ' in? ' + tih);
if (eval('' + tih.split(defst).length) > 2 && 1 == 7) {
ahh.push('doverlay' + ione + '~' + document.getElementById('mysel').innerHTML.split(' value="' + defst + '">')[1].split('<')[0]);
ione++;
defclass='' + ahh.length;
}
document.getElementById(ovid).innerHTML=tih.replace(defst, '<span id=myspan' + mss + ' class=highlight' + defclass + ' title="">' + defst + '</span>');
}
}
if (document.getElementById('myspan' + mss)) {
// document.getElementById('myspan' + mss).className='highlight' + ahh.length;
//alert('mss=' + mss + ' oh=' + document.getElementById('myspan' + mss).outerHTML);
nextih=document.getElementById('myspan' + mss).outerHTML;
tarectis=document.getElementById('myspan' + mss).getBoundingClientRect();
document.getElementById(ovid).style.position='absolute';
document.getElementById(ovid).style.top='' + tarectis.top + 'px';
document.getElementById(ovid).style.left='' + tarectis.left + 'px';
document.getElementById(ovid).style.width='' + tarectis.width + 'px';
document.getElementById(ovid).style.height='' + tarectis.height + 'px';
if (tbit != '') {
document.getElementById(ovid).title=tbit;
} else {
document.getElementById(ovid).title=document.getElementById('myspan' + mss).title;
}
//document.getElementById(ovid).className='highlight' + ahh.length;
document.getElementById(ovid).innerHTML=nextih;
}
if (eval('' + ahh.length) > 0) {
for (ihh=0; ihh<ahh.length; ihh++) {
if (ahh[ihh].trim() != '') {
if (document.getElementById('divhost').innerHTML.replace(/\:\ /g,':').indexOf(ahh[ihh].split('~')[1]) != -1) {
//alert(ahh[ihh]);
divoverlayclone(ahh[ihh].split('~')[0], ahh[ihh].split('~')[1]);
} else {
document.getElementById(ahh[ihh].split('~')[0]).innerHTML='';
}
}
}
}
}

… now in …


Previous relevant CSS Backdrop Filter Recursive Iframe Tutorial is shown below.

CSS Backdrop Filter Recursive Iframe Tutorial

CSS Backdrop Filter Recursive Iframe Tutorial

Today’s blog posting calls on the previous …

  • Image Filter Display Tutorial … and asking the question we had making this tutorial …

    Can the CSS filter property applications to HTML img elements also be applied to any form of “background” anything?

    … with an answer …

  • Sort of … if by “background” we can say “backdrop” to a nested, say, HTML div element, with some wording, in turn hosted by a, say, HTML div element that has a “background” image going on.

    … via CSS properties like …

    backdrop-filter: sepia(100%);

    … usage

Today’s work clones off a clone (using the work of yesterday’s CSS Mask HTML Element Recursive Iframe Tutorial) with a new “how we got there” initial cloned draft web application also shown below.


Previous relevant CSS Mask HTML Element Recursive Iframe Tutorial is shown below.

CSS Mask HTML Element Recursive Iframe Tutorial

CSS Mask HTML Element Recursive Iframe Tutorial

Often concept ideas you have for web applications have so much in common with something you’ve been working on, you’d be pretty foolish to not heed the adage …

  • Don’t let the perfect be the enemy of the good.

    … and one way we find to help here is …

  • “cloning” web applications on the understanding that what they have in common so far outweighs what the differences are that you push ahead, and wait and see what the issues are, after that initial “cloning” (usually) huge saving of development time

With that in mind, today, we’re adding off yesterday’s CSS Background Position Revisit Recursive Iframe Tutorial efforts, a …


Mask an HTML Element via CSS

… clone of it with those “midstream” SMS and email recursive iframe smarts (built in) to create a new “how we got there” initial cloned draft web application also shown below.


Previous relevant CSS Background Position Revisit Recursive Iframe Tutorial is shown below.

CSS Background Position Revisit Recursive Iframe Tutorial

CSS Background Position Revisit Recursive Iframe Tutorial

Onto yesterday’s CSS Background Position Revisit Tutorial, today we’re offering …

  • SMS … or …
  • email

… means of sharing your CSS work, as an interactive user, but on this occasion, we have a big gulf regarding what these two options can achieve, due to data length limits.

  • SMS … just the last styling change is transferred to the recipient as what they see … whereas …
  • email … records all user changes to the blockquote element and presents them to the recipient with the most recent topmost down to the original down the bottom of a stack of HTML iframe elements called recursively

So, what do we mean by “called recursively“? Well, like a linked list, our web application always contains an HTML iframe initially …


<iframe frameborder=0 src='/About_Us.html' id=ifbot style=display:none;width:100%;height:6000px;></iframe>

… down the bottom of it’s body element. The document.body onload event Javascript logic call as per onl(”); now includes


var inta='', startstyle='';
var intas=[];
if (document.URL.indexOf('Cjxi') != -1) {
intas=document.URL.split('Cjxi');
for (var inm=1; inm<intas.length; inm++) {
intas[eval(-1 + inm)]=decodeURIComponent(decodeURIComponent(escape(atob('Cjxi' + intas[inm]))));
}
}
inta=(location.search + ('' + location.hash).replace(/^undefined/g,'').replace(/^null/g,'')).split('taidea' + eqis)[1] ? ourdecodeURIComponent((location.search + ('' + location.hash).replace(/^undefined/g,'').replace(/^null/g,'')).split('taidea' + eqis)[1].split('&')[0]).replace(/\+/g,plus) : '';
if (inta.indexOf('background') == 0) {
startstyle=inta;
inta='';
}
var preint='';
preint=inta.split('blockquote')[0];
if (eval('' + intas.length) == 0) {
intas=(inta + ' ').substring(preint.length).split('<blockquote');
}
var nextinta='';


function onl(altta) {
var outta=inta;
if (altta == '' && eval('' + intas.length) > 1) {
nextinta=inta.replace(preint + intas[0], '');
document.getElementById('hrbot').style.display='block';
if (is64) {
document.getElementById('ifbot').src=document.URL.split('?')[0].split('#')[0] + '?#taidea=' + ourencodeURIComponent(nextinta);
} else {
document.getElementById('ifbot').src=document.URL.split('?')[0].split('#')[0] + '?#taidea=' + encodeURIComponent(nextinta);
}
document.getElementById('ifbot').style.display='block';
inta=preint + intas[0];
outta=inta;
intas=[];
}

if (altta == '' && inta != '') {
if (eval('' + inta.split('repeat;').length) > 1) {
origdefopt=(inta.split('repeat;')[1].split(';')[0].split('"')[0] + ';').replace(/^\;/g,'');
document.getElementById('defopt').innerHTML='Styling idea [' + origdefopt + ']';
defoptit=origdefopt;
}
}
if (altta != '') { outta=altta; }
if (outta == '') {
outta=document.getElementById('divhost').innerHTML;
} else {
document.getElementById('divhost').innerHTML=outta;
document.getElementById('taidea').value=document.getElementById('divhost').innerHTML;
if (altta != '') {
if (eval('' + altta.split('repeat;').length) > 1) {
defoptit=(altta.split('repeat;')[1].split(';')[0].split('"')[0] + ';').replace(/^\;/g,'');
document.getElementById('defopt').innerHTML='Styling idea [' + defoptit + ']';
}
}
}
if (document.getElementById('taidea').value.indexOf(' data-yourown=""') == -1 && document.getElementById('taidea').value.indexOf(' data-yourown="') != -1) {
var newuns=document.getElementById('taidea').value.split(' data-yourown="')[1].split('"')[0].split(';,');
for (var inew=0; inew<newuns.length; inew++) {
if (document.getElementById('mysel').innerHTML.indexOf(newuns[inew].replace(/\;$/g,'') + ';') == -1) {
document.getElementById('mysel').innerHTML+='<option value="' + newuns[inew].replace(/\;$/g,'') + ';">' + newuns[inew].replace(/\;$/g,'') + ';</option>';
}
}
}
if (altta == '') {
if (startstyle != '') {
document.getElementById('divhost').innerHTML=document.getElementById('divhost').innerHTML.replace(document.getElementById('divhost').innerHTML.split(' style="')[1].split('"')[0], startstyle);
document.getElementById('taidea').value=document.getElementById('divhost').innerHTML;
}
sofares=document.getElementById('divhost').innerHTML;
setInterval(keeplooking, 5000);
}
//else if (sofares.indexOf(document.getElementById('divhost').innerHTML) == -1) {
//sofares+=document.getElementById('divhost').innerHTML;
//}
}


function keeplooking() {
if (sofares.indexOf(document.getElementById('divhost').innerHTML) == -1) {
var vs=sofares;
sofares=document.getElementById('divhost').innerHTML + vs;
}
}

… to help make this recursion happen in the changed “second draft” web application also shown below.


Previous relevant CSS Background Position Revisit Tutorial is shown below.

CSS Background Position Revisit Tutorial

CSS Background Position Revisit Tutorial

We are great admirers of HTML and CSS regarding the way multiple background images are possible behind an HTML element.

To get to a multiple background image scenario (or even single ones regarding the basis for this blog posting’s creation), the “Making Of” yesterday’s AlmaLinux Astronomy via PHP and Python PyEphem Revisit Tutorial we thought needed further scrutiny.

It’s the HTML blockquote background image of Nala and Luna of most interest, at least to us. It involved the use of CSS …


background-position-x:right;

… property, for our first time, that we can remember that is.

The blockquote styling did something to our …

  1. background-size:contain;
  2. background-repeat:no-repeat;

… “dynamic duo”, again, property combination, truncating imagery to the right (where Nala and Luna, the stars of the show, were) for the first time we’ve ever seen. We were forced to relook at all the background-position type styling properties, and that’s when we came across background-position-x:right as a way to get “the stars” back into the picture.

From there, we thought it might be good to write a proof of concept textarea based showing of the styling of that blockquote element involved, and allow the user to modify it either …

  • within the textarea element, on tabbing out of it … or via …
  • some set dropdown alternative CSS property suggestions … and in amongst those dropdown options, via …
  • enter user CSS properties of interest

… to see, dynamically, what happens to the WordPress styling conditioned blockquote rendition above the form, to confirm what your CSS would do, using our “first draft” web application also shown below …


Previous relevant AlmaLinux Astronomy via PHP and Python PyEphem Revisit Tutorial is shown below.

AlmaLinux Astronomy via PHP and Python PyEphem Revisit Tutorial

AlmaLinux Astronomy via PHP and Python PyEphem Revisit Tutorial

Further to AlmaLinux Astronomy via PHP and Python PyEphem Tutorial

  • these days RJM Programming is still on AlmaLinux …
  • but on a different IP address and web server to that previous blog posting …
  • but PHP versions have not changed, or not enough to cause any consternation … hence the “relative silence” on our part about it all

… but, even so, “things can go wrong”, and on a revisit to our Astronomy web application “things went wrong” …

Who’d have thought it?!

One of the potential issues was resolved with Code Difference AlmaLinux New Webserver Issue Tutorial allowing for exec and shell_exec usage, for which we thank our web hosters, Crazy Domains. There are other players in this astronomy web application though, they being …

  • Python … called via PHP exec … calling …
  • PyEphem module (most importantly)

… and the investigation should start at Python to our mind. Our initial investigation into ephem_astronomy.php code first looking for a path through to Python at …


/usr/bin/python

… and we saw the difference in Terminal sessions asking three things of our two web servers …

Web server The ask … The result is …
Old which python /bin/python
New which python /usr/bin/which: no python in ([new web server’s path for root account])
Old which python3 /bin/python3
New which python3 /bin/python3
Old ls -la /usr/bin/python*
lrwxrwxrwx 1 root root 9 Mar 12 03:06 /usr/bin/python -> ./python3
lrwxrwxrwx 1 root root 9 Mar 12 03:00 /usr/bin/python3 -> python3.9
-rwxr-xr-x 1 root root 15624 Mar 12 03:00 /usr/bin/python3.9
-rwxr-xr-x 1 root root 61 Mar 12 03:00 /usr/bin/python3.9-config
-rwxr-xr-x 1 root root 3624 Mar 12 02:53 /usr/bin/python3.9-x86_64-config
lrwxrwxrwx 1 root root 16 Mar 12 03:00 /usr/bin/python3-config -> python3.9-config
-rwxr-xr-x 1 root root 980 Mar 26 2022 /usr/bin/python3-html2text
lrwxrwxrwx 1 root root 16 Mar 12 03:00 /usr/bin/python-config -> ./python3-config
lrwxrwxrwx 1 root root 17 Mar 26 2022 /usr/bin/python-html2text -> python3-html2text
New ls -la /usr/bin/python*
lrwxrwxrwx 1 root root 16 Mar 12 03:00 /usr/bin/python-config -> ./python3-config
lrwxrwxrwx 1 root root 17 Mar 26 2022 /usr/bin/python-html2text -> python3-html2text
lrwxrwxrwx 1 root root 9 Mar 12 03:00 /usr/bin/python3 -> python3.9
lrwxrwxrwx 1 root root 16 Mar 12 03:00 /usr/bin/python3-config -> python3.9-config
-rwxr-xr-x 1 root root 980 Mar 26 2022 /usr/bin/python3-html2text
-rwxr-xr-x 1 root root 15624 Mar 12 03:00 /usr/bin/python3.9
-rwxr-xr-x 1 root root 61 Mar 12 03:00 /usr/bin/python3.9-config
-rwxr-xr-x 1 root root 3624 Mar 12 02:53 /usr/bin/python3.9-x86_64-config

… and so, after doing the research regarding our question …

On linux is there a better way out of alias versus soft link to solve a path based issue?

… giving the Google AI Overview, thanks, answer …

For solving path-based issues in Linux, symbolic links are generally better than aliases. Aliases are shell-specific and don’t offer the same level of system-wide functionality as symbolic links. Symbolic links, or symlinks, act as references to files or directories within the file system, making them a more robust and versatile solution for path-related problems.

… we think points to Equivalent of alias for a symbolic link and fitting in with our preferences, too, getting us in Terminal on the new web server to go …


$ cd /usr/bin
$ ln -s ./python3.9 ./python

… to end up with …


$ ls -la /usr/bin/python*
lrwxrwxrwx 1 root root 11 Jun 18 07:54 /usr/bin/python -> ./python3.9
lrwxrwxrwx 1 root root 16 Mar 12 03:00 /usr/bin/python-config -> ./python3-config
lrwxrwxrwx 1 root root 17 Mar 26 2022 /usr/bin/python-html2text -> python3-html2text
lrwxrwxrwx 1 root root 9 Mar 12 03:00 /usr/bin/python3 -> python3.9
lrwxrwxrwx 1 root root 16 Mar 12 03:00 /usr/bin/python3-config -> python3.9-config
-rwxr-xr-x 1 root root 980 Mar 26 2022 /usr/bin/python3-html2text
-rwxr-xr-x 1 root root 15624 Mar 12 03:00 /usr/bin/python3.9
-rwxr-xr-x 1 root root 61 Mar 12 03:00 /usr/bin/python3.9-config
-rwxr-xr-x 1 root root 3624 Mar 12 02:53 /usr/bin/python3.9-x86_64-config
$ which python
/bin/python

… and a better functioning Astronomy web application, as well as the chance other PHP calling Python scenarios being fixed, ahead of (web application and PHP and Python code) revisits, there and then. However, if all this sounds trepidacious, or impossible (lots of web hosting would not allow you anywhere close to “underlying Operating System anything”), or your server does not support Soft (ie. Symbolic) Links (eg. Windows) you could change this way the ephem_astronomy.php PHP code to fit with the original environment ahead of creating that new Soft (ie. Symbolic) Link used in that inhouse Astronomy PHP calling Python module web application.


Previous relevant AlmaLinux Astronomy via PHP and Python PyEphem Tutorial is shown below.

AlmaLinux Astronomy via PHP and Python PyEphem Tutorial

AlmaLinux Astronomy via PHP and Python PyEphem Tutorial

You might recall reading the previous PHP/Javascript/HTML and Python PyEphem Moon Angle Tutorial below how we got into some Astronomy via …

  • PHP … calling, via exec
  • Python … (alas, no 3P’s Perl here) … and it’s …
  • PyEphem … module skilled at Astronomy … installed via …
  • Pip … (alas, no Estella)

… so from that … let’s see … we get The Four TopsPipsP’s (in relation to lemon trees … tee hee).

Well, to make Moon Angles and Astronomy Helper web applications work on AlmaLinux we needed to attend to a couple of install matters …

  • install the Python package manager Pip via (the AlmaLinux PHP dnf package manager) …

    dnf install python3-pip.noarch
  • install the Python module, helping out with Astronomy matters, called PyEphem via …

    sudo pip install pyephem

… to be in a position to progress, and then add a check for existence of /usr/bin/python (for AlmaLinux) in preference to /usr/local/bin/python3.3 (for CentOS) as the final measure needed to start getting results back to any PHP overseers …


Previous relevant PHP/Javascript/HTML and Python PyEphem Moon Angle Tutorial is shown below.

PHP/Javascript/HTML and Python PyEphem Moon Angle Tutorial

PHP/Javascript/HTML and Python PyEphem Moon Angle Tutorial

A long time ago now we presented PHP/Javascript/HTML Moon Angle Tutorial but now we feel is a good time for it to get a makeover. Why is that? Well, we have the relatively new discovery of the very useful Python PyEphem module to thank for that.

As far as the new version goes we now offer a Moon Angle “time of transit (and relative to now)” calculation, which we think will be of more use to users.

The Moon Angle at Transit calculations again involve the Sublunary Point as the position on Earth directly above which is Moon is located. Add in the Python PyEphem work and some more terminology that may interest you could involve …

… within the Python of interest, a snapshot of which is shown below, but which changes each time somebody recreates this sublunarx.py


import ephem
import math
import time
from datetime import datetime, timedelta
greenwich = ephem.Observer()
greenwich.lat = "0"
greenwich.lon = "0"
greenwich.date = datetime.utcnow()
moon = ephem.Moon(greenwich)
moon.compute(greenwich.date)
moon_lon = math.degrees(moon.ra - greenwich.sidereal_time() )
if moon_lon < -180.0 :
moon_lon = 360.0 + moon_lon
elif moon_lon > 180.0 :
moon_lon = moon_lon - 360.0
moon_lat = math.degrees(moon.dec)
d1 = ephem.next_full_moon(greenwich.date)
d2 = ephem.next_new_moon(greenwich.date)
greenwich.lat = "151:10.586502000000001"
greenwich.lon = "-33:54.445878"
greenwich.date = datetime.utcnow()
moon = ephem.Moon(greenwich)
moon.compute(greenwich.date)
betw = (greenwich.next_transit(moon) - greenwich.date) * 86400.0 / 60.0 / 60.0
gnt = greenwich.next_transit(moon)
greenwich.date = gnt
moon = ephem.Moon(greenwich)
moon.compute(gnt)
moon_lon_x = math.degrees(moon.ra - greenwich.sidereal_time() )
if moon_lon_x < -180.0 :
moon_lon_x = 360.0 + moon_lon_x
elif moon_lon_x > 180.0 :
moon_lon_x = moon_lon_x - 360.0
moon_lat_y = math.degrees(moon.dec)
print('%s %s %s %s %s %s %s %f' % (moon_lon, moon_lat, d1, d2, gnt, moon_lon_x, moon_lat_y, betw))
quit()

The Moon Angle web application live run, which we welcome you to try, has the underlying PHP moon_angle_now_at.php that supervises the Python exemplied above, and which featured these changes to make this happen.


Previous relevant PHP/Javascript/HTML Moon Angle Tutorial is shown below.

PHP/Javascript/HTML Moon Angle Tutorial

PHP/Javascript/HTML Moon Angle Tutorial

Here is a tutorial that calculates Noon Moon Angles from Earth via the entry of Latitude and Longitude. The calculation of noon moon angles uses the concept of Sublunary Point, which is explained in the quote from Wikipedia below.

The sublunary point (Latin sub-lunar, under the moon ‘, from Latin) is the one place on earth where the moon in exactly the zenith is. He is the point where the line connecting the centers of the Earth and Moon intersects the Earth’s surface. The point is a common auxiliary point to observe the Moon in the celestial mechanics and astronomical phenomenology , and in particular the theory of the tides , as well as the theory of eclipses .

The calculation of the point corresponding to the determination of the geocentric coordinates of the Moon, it has the same longitude and latitude , as the moon astronomical length and width has – both are denoted by φ and β.

The Javascript embellishments in this tutorial mainly revolve around:

The use of window.open can sometimes be blocked by web browsers depending on their settings and you can read a bit more about such issues here.

Useful tutorials that helped, and we give thanks to, were:

Here is a link to a live run. (The way it changed on 1/12/2013 to have a dropdown of placenames as extra functionality will be explained in a tutorial called PHP/Javascript/HTML Geographical Placename Integration Tutorial on 3/12/2013.)

Here is a link to some downloadable PHP programming source code which you may want to rename to moon_angle_now_at.php

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

Posted in Ajax, eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

CSS Web Application External Javascript Peer to Peer Tutorial

CSS Web Application External Javascript Peer to Peer Tutorial

CSS Web Application External Javascript Peer to Peer Tutorial

We tackle a few more issues onto yesterday’s CSS Web Application Highlighted Text Tutorial with …

  • peer to peer linking of these 3 (so far) CSS referencing web applications via a new header element dropdown element
  • some better email functionality when the web application is hosted such as it is with the “shown below” links in this blog posting
  • allow a change of background image to use for the Backdrop Filter web application

The first two used for their work the code of a new css_webapps_peer.js external Javascript interfacing with …


Previous relevant CSS Web Application Highlighted Text Tutorial is shown below.

CSS Web Application Highlighted Text Tutorial

CSS Web Application Highlighted Text Tutorial

You may have been around reading this blog to recall Sentence Text Word Underlining Primer Tutorial‘s discussions regarding the text data talents of HTML element type textarea up against div and the resultant table reflecting our views on this …

Text Talents of HTML Elements
Textarea … versus … Div
And CSS 3D Transformation Matrix Making Of Interactive Integration Tutorial set out how we see the pros and cons as …
Text Functionality Issue HTML Element Type Strength Weakness (where a “Yes” is like … “Oh No!”)
Display Monocolour Text Textarea Yes
Div Yes
Display Editable Text Textarea Yes
Div Yes
Display Multicolour Text Textarea Yes
Div Yes

… and it’s assertion that regarding Display Multicolour Text the use of textarea elements were not suitable. Well, today, we do not resile from that view, when you consider a textarea element on it’s own, but what if it gets “overlay” type of help from div nesting span elements (and we have “reverse corollaries” here with SVG tspan element usage in SVG Tspan Element Primer Tutorial) with background colour and transparent text, leading to capabilities where textarea text of relevance can be highlighted.

Sounds good?! Yes, but it must be said we could have just replaced the textarea elements (within our CSS Themed suit of web applications of recent times, talked about with yesterday’s CSS Backdrop Filter Recursive Iframe Tutorial) with div ones where contenteditable=true could still allow for interactivity, but for the reasons …

  • we wanted to see if highlighting text within a textarea could be achieved … Spoiler Alert: yes, it’s possible … as well as
  • textarea elements have a great resizing “native” functionality
  • textarea elements feel far more “the go” when asking for user interactive entry data that can contain linefeeds
  • over time we find more and more use for the textarea attributes value and innerHTML as separately useful dual ways of populating the element, especially in the scenario with text data where the latter is useful to initiate with text data containing < and > which gets mapped to &lt; and &gt; respectively once the code looks at that textarea‘s value attribute … Cute, huh?! In fairness, though div contenteditable=true also have interesting interplay with innerHTML and innerText attributes going on in this respect too.

… we’re carrying on with textarea element interactive entry usage with this current suite of CSS based web applications.

Here’s the new Javascript function crucial to making this possible …


function divoverlayclone(ovid, indefst) {
var tih='', taih=document.getElementById('divhost').innerHTML, nextih='', tbit='', huhs=[], ihuh=0, mss='', ahh=[], ione=1, ihh=0;
var tarectis=document.getElementById('taidea').getBoundingClientRect();
if (ovid == '') { ovid='doverlay'; } else {
mss=ovid.replace('doverlay','');
for (var iou=0; iou<eval('' + mss); iou++) {
ahh.push('');
}
}
var defclass=(' ' + mss).slice(-1).trim();
for (var itih=taih.indexOf('<'); itih<taih.length; itih++) {
if (taih.substring(itih).substring(0,1) == String.fromCharCode(10)) {
tih+='<br>';
} else if (taih.substring(itih).substring(0,1) == '<') {
tih+='<';
} else if (taih.substring(itih).substring(0,1) == '>') {
tih+='>';
} else {
tih+=taih.substring(itih).substring(0,1);
}
}
document.getElementById(ovid).style.position='absolute';
document.getElementById(ovid).style.top='' + tarectis.top + 'px';
document.getElementById(ovid).style.left='' + tarectis.left + 'px';
document.getElementById(ovid).style.width='' + tarectis.width + 'px';
document.getElementById(ovid).style.height='' + tarectis.height + 'px';
document.getElementById(ovid).style.fontSize = window.getComputedStyle(document.getElementById('taidea'),null).fontSize || document.getElementById('taidea').style.fontSize || document.getElementById('taidea').currentStyle.getCurrentProperty('font-size');
if (indefst.trim() != '') {
//alert('0:' + indefst);
if (document.getElementById('divhost').innerHTML.indexOf(indefst.replace(':',': ')) != -1) {
//alert('00:' + indefst);
if (tih.indexOf(indefst.replace(':',': ') + '">') != -1) {
document.getElementById(ovid).innerHTML=tih.replace(indefst.replace(':',': ') + '">', '<span id=myspan' + mss + ' class=highlight' + (' ' + mss).slice(-1).trim() + ' title="' + indefst.replace(':',': ') + '">' + indefst.replace(':',': ') + '</span>">');
} else {
document.getElementById(ovid).innerHTML=tih.replace(indefst.replace(':',': '), '<span id=myspan' + mss + ' class=highlight' + (' ' + mss).slice(-1).trim() + ' title="' + indefst.replace(':',': ') + '">' + indefst.replace(':',': ') + '</span>');
}
} else if (document.getElementById('divhost').innerHTML.indexOf(indefst) != -1) {
//alert('000:' + indefst);
if (tih.indexOf(indefst + '">') != -1) {
document.getElementById(ovid).innerHTML=tih.replace(indefst + '">', '<span id=myspan' + mss + ' class=highlight' + (' ' + mss).slice(-1).trim() + ' title="' + indefst + '">' + indefst + '</span>">');
} else {
document.getElementById(ovid).innerHTML=tih.replace(indefst, '<span id=myspan' + mss + ' class=highlight' + (' ' + mss).slice(-1).trim() + ' title="' + indefst + '">' + indefst + '</span>');
}
} else {
return '';
}
} else {
//alert(defst);
if (defst.indexOf(';') == -1) {
huhs=defst.split(' ');
//alert('2:' + huhs[0]);
for (ihuh=0; ihuh<huhs.length; ihuh++) {
if (document.getElementById('mysel').innerHTML.indexOf(' value="' + huhs[ihuh] + '">') != -1) {
//alert('3:' + huhs[0]);
tbit+=document.getElementById('mysel').innerHTML.split(' value="' + huhs[ihuh] + '">')[1].split('<')[0];
ahh.push('doverlay' + ione + '~' + document.getElementById('mysel').innerHTML.split(' value="' + huhs[ihuh] + '">')[1].split('<')[0]);
ione++;
}
}
defclass='' + ahh.length;
//alert('defclass=' + defclass);
document.getElementById(ovid).innerHTML=tih.replace(defst, '<span id=myspan' + mss + ' class=highlight' + defclass + ' title="' + tbit + '">' + defst + '</span>');
} else if (document.getElementById('mysel').innerHTML.indexOf(' value="' + defst + '">') != -1) {
if (eval('' + tih.split(defst).length) > 2) {
ahh.push('doverlay' + ione + '~' + document.getElementById('mysel').innerHTML.split(' value="' + defst + '">')[1].split('<')[0]);
ione++;
defclass='' + ahh.length;
}
document.getElementById(ovid).innerHTML=tih.replace(defst, '<span id=myspan' + mss + ' class=highlight' + defclass + ' title="' + document.getElementById('mysel').innerHTML.split(' value="' + defst + '">')[1].split('<')[0] + '">' + defst + '</span>');
} else {
//alert(defst + ' in? ' + tih);
if (eval('' + tih.split(defst).length) > 2 && 1 == 7) {
ahh.push('doverlay' + ione + '~' + document.getElementById('mysel').innerHTML.split(' value="' + defst + '">')[1].split('<')[0]);
ione++;
defclass='' + ahh.length;
}
document.getElementById(ovid).innerHTML=tih.replace(defst, '<span id=myspan' + mss + ' class=highlight' + defclass + ' title="">' + defst + '</span>');
}
}
if (document.getElementById('myspan' + mss)) {
// document.getElementById('myspan' + mss).className='highlight' + ahh.length;
//alert('mss=' + mss + ' oh=' + document.getElementById('myspan' + mss).outerHTML);
nextih=document.getElementById('myspan' + mss).outerHTML;
tarectis=document.getElementById('myspan' + mss).getBoundingClientRect();
document.getElementById(ovid).style.position='absolute';
document.getElementById(ovid).style.top='' + tarectis.top + 'px';
document.getElementById(ovid).style.left='' + tarectis.left + 'px';
document.getElementById(ovid).style.width='' + tarectis.width + 'px';
document.getElementById(ovid).style.height='' + tarectis.height + 'px';
if (tbit != '') {
document.getElementById(ovid).title=tbit;
} else {
document.getElementById(ovid).title=document.getElementById('myspan' + mss).title;
}
//document.getElementById(ovid).className='highlight' + ahh.length;
document.getElementById(ovid).innerHTML=nextih;
}
if (eval('' + ahh.length) > 0) {
for (ihh=0; ihh<ahh.length; ihh++) {
if (ahh[ihh].trim() != '') {
if (document.getElementById('divhost').innerHTML.replace(/\:\ /g,':').indexOf(ahh[ihh].split('~')[1]) != -1) {
//alert(ahh[ihh]);
divoverlayclone(ahh[ihh].split('~')[0], ahh[ihh].split('~')[1]);
} else {
document.getElementById(ahh[ihh].split('~')[0]).innerHTML='';
}
}
}
}
}

… now in …


Previous relevant CSS Backdrop Filter Recursive Iframe Tutorial is shown below.

CSS Backdrop Filter Recursive Iframe Tutorial

CSS Backdrop Filter Recursive Iframe Tutorial

Today’s blog posting calls on the previous …

  • Image Filter Display Tutorial … and asking the question we had making this tutorial …

    Can the CSS filter property applications to HTML img elements also be applied to any form of “background” anything?

    … with an answer …

  • Sort of … if by “background” we can say “backdrop” to a nested, say, HTML div element, with some wording, in turn hosted by a, say, HTML div element that has a “background” image going on.

    … via CSS properties like …

    backdrop-filter: sepia(100%);

    … usage

Today’s work clones off a clone (using the work of yesterday’s CSS Mask HTML Element Recursive Iframe Tutorial) with a new “how we got there” initial cloned draft web application also shown below.


Previous relevant CSS Mask HTML Element Recursive Iframe Tutorial is shown below.

CSS Mask HTML Element Recursive Iframe Tutorial

CSS Mask HTML Element Recursive Iframe Tutorial

Often concept ideas you have for web applications have so much in common with something you’ve been working on, you’d be pretty foolish to not heed the adage …

  • Don’t let the perfect be the enemy of the good.

    … and one way we find to help here is …

  • “cloning” web applications on the understanding that what they have in common so far outweighs what the differences are that you push ahead, and wait and see what the issues are, after that initial “cloning” (usually) huge saving of development time

With that in mind, today, we’re adding off yesterday’s CSS Background Position Revisit Recursive Iframe Tutorial efforts, a …


Mask an HTML Element via CSS

… clone of it with those “midstream” SMS and email recursive iframe smarts (built in) to create a new “how we got there” initial cloned draft web application also shown below.


Previous relevant CSS Background Position Revisit Recursive Iframe Tutorial is shown below.

CSS Background Position Revisit Recursive Iframe Tutorial

CSS Background Position Revisit Recursive Iframe Tutorial

Onto yesterday’s CSS Background Position Revisit Tutorial, today we’re offering …

  • SMS … or …
  • email

… means of sharing your CSS work, as an interactive user, but on this occasion, we have a big gulf regarding what these two options can achieve, due to data length limits.

  • SMS … just the last styling change is transferred to the recipient as what they see … whereas …
  • email … records all user changes to the blockquote element and presents them to the recipient with the most recent topmost down to the original down the bottom of a stack of HTML iframe elements called recursively

So, what do we mean by “called recursively“? Well, like a linked list, our web application always contains an HTML iframe initially …


<iframe frameborder=0 src='/About_Us.html' id=ifbot style=display:none;width:100%;height:6000px;></iframe>

… down the bottom of it’s body element. The document.body onload event Javascript logic call as per onl(”); now includes


var inta='', startstyle='';
var intas=[];
if (document.URL.indexOf('Cjxi') != -1) {
intas=document.URL.split('Cjxi');
for (var inm=1; inm<intas.length; inm++) {
intas[eval(-1 + inm)]=decodeURIComponent(decodeURIComponent(escape(atob('Cjxi' + intas[inm]))));
}
}
inta=(location.search + ('' + location.hash).replace(/^undefined/g,'').replace(/^null/g,'')).split('taidea' + eqis)[1] ? ourdecodeURIComponent((location.search + ('' + location.hash).replace(/^undefined/g,'').replace(/^null/g,'')).split('taidea' + eqis)[1].split('&')[0]).replace(/\+/g,plus) : '';
if (inta.indexOf('background') == 0) {
startstyle=inta;
inta='';
}
var preint='';
preint=inta.split('blockquote')[0];
if (eval('' + intas.length) == 0) {
intas=(inta + ' ').substring(preint.length).split('<blockquote');
}
var nextinta='';


function onl(altta) {
var outta=inta;
if (altta == '' && eval('' + intas.length) > 1) {
nextinta=inta.replace(preint + intas[0], '');
document.getElementById('hrbot').style.display='block';
if (is64) {
document.getElementById('ifbot').src=document.URL.split('?')[0].split('#')[0] + '?#taidea=' + ourencodeURIComponent(nextinta);
} else {
document.getElementById('ifbot').src=document.URL.split('?')[0].split('#')[0] + '?#taidea=' + encodeURIComponent(nextinta);
}
document.getElementById('ifbot').style.display='block';
inta=preint + intas[0];
outta=inta;
intas=[];
}

if (altta == '' && inta != '') {
if (eval('' + inta.split('repeat;').length) > 1) {
origdefopt=(inta.split('repeat;')[1].split(';')[0].split('"')[0] + ';').replace(/^\;/g,'');
document.getElementById('defopt').innerHTML='Styling idea [' + origdefopt + ']';
defoptit=origdefopt;
}
}
if (altta != '') { outta=altta; }
if (outta == '') {
outta=document.getElementById('divhost').innerHTML;
} else {
document.getElementById('divhost').innerHTML=outta;
document.getElementById('taidea').value=document.getElementById('divhost').innerHTML;
if (altta != '') {
if (eval('' + altta.split('repeat;').length) > 1) {
defoptit=(altta.split('repeat;')[1].split(';')[0].split('"')[0] + ';').replace(/^\;/g,'');
document.getElementById('defopt').innerHTML='Styling idea [' + defoptit + ']';
}
}
}
if (document.getElementById('taidea').value.indexOf(' data-yourown=""') == -1 && document.getElementById('taidea').value.indexOf(' data-yourown="') != -1) {
var newuns=document.getElementById('taidea').value.split(' data-yourown="')[1].split('"')[0].split(';,');
for (var inew=0; inew<newuns.length; inew++) {
if (document.getElementById('mysel').innerHTML.indexOf(newuns[inew].replace(/\;$/g,'') + ';') == -1) {
document.getElementById('mysel').innerHTML+='<option value="' + newuns[inew].replace(/\;$/g,'') + ';">' + newuns[inew].replace(/\;$/g,'') + ';</option>';
}
}
}
if (altta == '') {
if (startstyle != '') {
document.getElementById('divhost').innerHTML=document.getElementById('divhost').innerHTML.replace(document.getElementById('divhost').innerHTML.split(' style="')[1].split('"')[0], startstyle);
document.getElementById('taidea').value=document.getElementById('divhost').innerHTML;
}
sofares=document.getElementById('divhost').innerHTML;
setInterval(keeplooking, 5000);
}
//else if (sofares.indexOf(document.getElementById('divhost').innerHTML) == -1) {
//sofares+=document.getElementById('divhost').innerHTML;
//}
}


function keeplooking() {
if (sofares.indexOf(document.getElementById('divhost').innerHTML) == -1) {
var vs=sofares;
sofares=document.getElementById('divhost').innerHTML + vs;
}
}

… to help make this recursion happen in the changed “second draft” web application also shown below.


Previous relevant CSS Background Position Revisit Tutorial is shown below.

CSS Background Position Revisit Tutorial

CSS Background Position Revisit Tutorial

We are great admirers of HTML and CSS regarding the way multiple background images are possible behind an HTML element.

To get to a multiple background image scenario (or even single ones regarding the basis for this blog posting’s creation), the “Making Of” yesterday’s AlmaLinux Astronomy via PHP and Python PyEphem Revisit Tutorial we thought needed further scrutiny.

It’s the HTML blockquote background image of Nala and Luna of most interest, at least to us. It involved the use of CSS …


background-position-x:right;

… property, for our first time, that we can remember that is.

The blockquote styling did something to our …

  1. background-size:contain;
  2. background-repeat:no-repeat;

… “dynamic duo”, again, property combination, truncating imagery to the right (where Nala and Luna, the stars of the show, were) for the first time we’ve ever seen. We were forced to relook at all the background-position type styling properties, and that’s when we came across background-position-x:right as a way to get “the stars” back into the picture.

From there, we thought it might be good to write a proof of concept textarea based showing of the styling of that blockquote element involved, and allow the user to modify it either …

  • within the textarea element, on tabbing out of it … or via …
  • some set dropdown alternative CSS property suggestions … and in amongst those dropdown options, via …
  • enter user CSS properties of interest

… to see, dynamically, what happens to the WordPress styling conditioned blockquote rendition above the form, to confirm what your CSS would do, using our “first draft” web application also shown below …


Previous relevant AlmaLinux Astronomy via PHP and Python PyEphem Revisit Tutorial is shown below.

AlmaLinux Astronomy via PHP and Python PyEphem Revisit Tutorial

AlmaLinux Astronomy via PHP and Python PyEphem Revisit Tutorial

Further to AlmaLinux Astronomy via PHP and Python PyEphem Tutorial

  • these days RJM Programming is still on AlmaLinux …
  • but on a different IP address and web server to that previous blog posting …
  • but PHP versions have not changed, or not enough to cause any consternation … hence the “relative silence” on our part about it all

… but, even so, “things can go wrong”, and on a revisit to our Astronomy web application “things went wrong” …

Who’d have thought it?!

One of the potential issues was resolved with Code Difference AlmaLinux New Webserver Issue Tutorial allowing for exec and shell_exec usage, for which we thank our web hosters, Crazy Domains. There are other players in this astronomy web application though, they being …

  • Python … called via PHP exec … calling …
  • PyEphem module (most importantly)

… and the investigation should start at Python to our mind. Our initial investigation into ephem_astronomy.php code first looking for a path through to Python at …


/usr/bin/python

… and we saw the difference in Terminal sessions asking three things of our two web servers …

Web server The ask … The result is …
Old which python /bin/python
New which python /usr/bin/which: no python in ([new web server’s path for root account])
Old which python3 /bin/python3
New which python3 /bin/python3
Old ls -la /usr/bin/python*
lrwxrwxrwx 1 root root 9 Mar 12 03:06 /usr/bin/python -> ./python3
lrwxrwxrwx 1 root root 9 Mar 12 03:00 /usr/bin/python3 -> python3.9
-rwxr-xr-x 1 root root 15624 Mar 12 03:00 /usr/bin/python3.9
-rwxr-xr-x 1 root root 61 Mar 12 03:00 /usr/bin/python3.9-config
-rwxr-xr-x 1 root root 3624 Mar 12 02:53 /usr/bin/python3.9-x86_64-config
lrwxrwxrwx 1 root root 16 Mar 12 03:00 /usr/bin/python3-config -> python3.9-config
-rwxr-xr-x 1 root root 980 Mar 26 2022 /usr/bin/python3-html2text
lrwxrwxrwx 1 root root 16 Mar 12 03:00 /usr/bin/python-config -> ./python3-config
lrwxrwxrwx 1 root root 17 Mar 26 2022 /usr/bin/python-html2text -> python3-html2text
New ls -la /usr/bin/python*
lrwxrwxrwx 1 root root 16 Mar 12 03:00 /usr/bin/python-config -> ./python3-config
lrwxrwxrwx 1 root root 17 Mar 26 2022 /usr/bin/python-html2text -> python3-html2text
lrwxrwxrwx 1 root root 9 Mar 12 03:00 /usr/bin/python3 -> python3.9
lrwxrwxrwx 1 root root 16 Mar 12 03:00 /usr/bin/python3-config -> python3.9-config
-rwxr-xr-x 1 root root 980 Mar 26 2022 /usr/bin/python3-html2text
-rwxr-xr-x 1 root root 15624 Mar 12 03:00 /usr/bin/python3.9
-rwxr-xr-x 1 root root 61 Mar 12 03:00 /usr/bin/python3.9-config
-rwxr-xr-x 1 root root 3624 Mar 12 02:53 /usr/bin/python3.9-x86_64-config

… and so, after doing the research regarding our question …

On linux is there a better way out of alias versus soft link to solve a path based issue?

… giving the Google AI Overview, thanks, answer …

For solving path-based issues in Linux, symbolic links are generally better than aliases. Aliases are shell-specific and don’t offer the same level of system-wide functionality as symbolic links. Symbolic links, or symlinks, act as references to files or directories within the file system, making them a more robust and versatile solution for path-related problems.

… we think points to Equivalent of alias for a symbolic link and fitting in with our preferences, too, getting us in Terminal on the new web server to go …


$ cd /usr/bin
$ ln -s ./python3.9 ./python

… to end up with …


$ ls -la /usr/bin/python*
lrwxrwxrwx 1 root root 11 Jun 18 07:54 /usr/bin/python -> ./python3.9
lrwxrwxrwx 1 root root 16 Mar 12 03:00 /usr/bin/python-config -> ./python3-config
lrwxrwxrwx 1 root root 17 Mar 26 2022 /usr/bin/python-html2text -> python3-html2text
lrwxrwxrwx 1 root root 9 Mar 12 03:00 /usr/bin/python3 -> python3.9
lrwxrwxrwx 1 root root 16 Mar 12 03:00 /usr/bin/python3-config -> python3.9-config
-rwxr-xr-x 1 root root 980 Mar 26 2022 /usr/bin/python3-html2text
-rwxr-xr-x 1 root root 15624 Mar 12 03:00 /usr/bin/python3.9
-rwxr-xr-x 1 root root 61 Mar 12 03:00 /usr/bin/python3.9-config
-rwxr-xr-x 1 root root 3624 Mar 12 02:53 /usr/bin/python3.9-x86_64-config
$ which python
/bin/python

… and a better functioning Astronomy web application, as well as the chance other PHP calling Python scenarios being fixed, ahead of (web application and PHP and Python code) revisits, there and then. However, if all this sounds trepidacious, or impossible (lots of web hosting would not allow you anywhere close to “underlying Operating System anything”), or your server does not support Soft (ie. Symbolic) Links (eg. Windows) you could change this way the ephem_astronomy.php PHP code to fit with the original environment ahead of creating that new Soft (ie. Symbolic) Link used in that inhouse Astronomy PHP calling Python module web application.


Previous relevant AlmaLinux Astronomy via PHP and Python PyEphem Tutorial is shown below.

AlmaLinux Astronomy via PHP and Python PyEphem Tutorial

AlmaLinux Astronomy via PHP and Python PyEphem Tutorial

You might recall reading the previous PHP/Javascript/HTML and Python PyEphem Moon Angle Tutorial below how we got into some Astronomy via …

  • PHP … calling, via exec
  • Python … (alas, no 3P’s Perl here) … and it’s …
  • PyEphem … module skilled at Astronomy … installed via …
  • Pip … (alas, no Estella)

… so from that … let’s see … we get The Four TopsPipsP’s (in relation to lemon trees … tee hee).

Well, to make Moon Angles and Astronomy Helper web applications work on AlmaLinux we needed to attend to a couple of install matters …

  • install the Python package manager Pip via (the AlmaLinux PHP dnf package manager) …

    dnf install python3-pip.noarch
  • install the Python module, helping out with Astronomy matters, called PyEphem via …

    sudo pip install pyephem

… to be in a position to progress, and then add a check for existence of /usr/bin/python (for AlmaLinux) in preference to /usr/local/bin/python3.3 (for CentOS) as the final measure needed to start getting results back to any PHP overseers …


Previous relevant PHP/Javascript/HTML and Python PyEphem Moon Angle Tutorial is shown below.

PHP/Javascript/HTML and Python PyEphem Moon Angle Tutorial

PHP/Javascript/HTML and Python PyEphem Moon Angle Tutorial

A long time ago now we presented PHP/Javascript/HTML Moon Angle Tutorial but now we feel is a good time for it to get a makeover. Why is that? Well, we have the relatively new discovery of the very useful Python PyEphem module to thank for that.

As far as the new version goes we now offer a Moon Angle “time of transit (and relative to now)” calculation, which we think will be of more use to users.

The Moon Angle at Transit calculations again involve the Sublunary Point as the position on Earth directly above which is Moon is located. Add in the Python PyEphem work and some more terminology that may interest you could involve …

… within the Python of interest, a snapshot of which is shown below, but which changes each time somebody recreates this sublunarx.py


import ephem
import math
import time
from datetime import datetime, timedelta
greenwich = ephem.Observer()
greenwich.lat = "0"
greenwich.lon = "0"
greenwich.date = datetime.utcnow()
moon = ephem.Moon(greenwich)
moon.compute(greenwich.date)
moon_lon = math.degrees(moon.ra - greenwich.sidereal_time() )
if moon_lon < -180.0 :
moon_lon = 360.0 + moon_lon
elif moon_lon > 180.0 :
moon_lon = moon_lon - 360.0
moon_lat = math.degrees(moon.dec)
d1 = ephem.next_full_moon(greenwich.date)
d2 = ephem.next_new_moon(greenwich.date)
greenwich.lat = "151:10.586502000000001"
greenwich.lon = "-33:54.445878"
greenwich.date = datetime.utcnow()
moon = ephem.Moon(greenwich)
moon.compute(greenwich.date)
betw = (greenwich.next_transit(moon) - greenwich.date) * 86400.0 / 60.0 / 60.0
gnt = greenwich.next_transit(moon)
greenwich.date = gnt
moon = ephem.Moon(greenwich)
moon.compute(gnt)
moon_lon_x = math.degrees(moon.ra - greenwich.sidereal_time() )
if moon_lon_x < -180.0 :
moon_lon_x = 360.0 + moon_lon_x
elif moon_lon_x > 180.0 :
moon_lon_x = moon_lon_x - 360.0
moon_lat_y = math.degrees(moon.dec)
print('%s %s %s %s %s %s %s %f' % (moon_lon, moon_lat, d1, d2, gnt, moon_lon_x, moon_lat_y, betw))
quit()

The Moon Angle web application live run, which we welcome you to try, has the underlying PHP moon_angle_now_at.php that supervises the Python exemplied above, and which featured these changes to make this happen.


Previous relevant PHP/Javascript/HTML Moon Angle Tutorial is shown below.

PHP/Javascript/HTML Moon Angle Tutorial

PHP/Javascript/HTML Moon Angle Tutorial

Here is a tutorial that calculates Noon Moon Angles from Earth via the entry of Latitude and Longitude. The calculation of noon moon angles uses the concept of Sublunary Point, which is explained in the quote from Wikipedia below.

The sublunary point (Latin sub-lunar, under the moon ‘, from Latin) is the one place on earth where the moon in exactly the zenith is. He is the point where the line connecting the centers of the Earth and Moon intersects the Earth’s surface. The point is a common auxiliary point to observe the Moon in the celestial mechanics and astronomical phenomenology , and in particular the theory of the tides , as well as the theory of eclipses .

The calculation of the point corresponding to the determination of the geocentric coordinates of the Moon, it has the same longitude and latitude , as the moon astronomical length and width has – both are denoted by φ and β.

The Javascript embellishments in this tutorial mainly revolve around:

The use of window.open can sometimes be blocked by web browsers depending on their settings and you can read a bit more about such issues here.

Useful tutorials that helped, and we give thanks to, were:

Here is a link to a live run. (The way it changed on 1/12/2013 to have a dropdown of placenames as extra functionality will be explained in a tutorial called PHP/Javascript/HTML Geographical Placename Integration Tutorial on 3/12/2013.)

Here is a link to some downloadable PHP programming source code which you may want to rename to moon_angle_now_at.php

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment

CSS Web Application Highlighted Text Tutorial

CSS Web Application Highlighted Text Tutorial

CSS Web Application Highlighted Text Tutorial

You may have been around reading this blog to recall Sentence Text Word Underlining Primer Tutorial‘s discussions regarding the text data talents of HTML element type textarea up against div and the resultant table reflecting our views on this …

Text Talents of HTML Elements
Textarea … versus … Div
And CSS 3D Transformation Matrix Making Of Interactive Integration Tutorial set out how we see the pros and cons as …
Text Functionality Issue HTML Element Type Strength Weakness (where a “Yes” is like … “Oh No!”)
Display Monocolour Text Textarea Yes
Div Yes
Display Editable Text Textarea Yes
Div Yes
Display Multicolour Text Textarea Yes
Div Yes

… and it’s assertion that regarding Display Multicolour Text the use of textarea elements were not suitable. Well, today, we do not resile from that view, when you consider a textarea element on it’s own, but what if it gets “overlay” type of help from div nesting span elements (and we have “reverse corollaries” here with SVG tspan element usage in SVG Tspan Element Primer Tutorial) with background colour and transparent text, leading to capabilities where textarea text of relevance can be highlighted.

Sounds good?! Yes, but it must be said we could have just replaced the textarea elements (within our CSS Themed suit of web applications of recent times, talked about with yesterday’s CSS Backdrop Filter Recursive Iframe Tutorial) with div ones where contenteditable=true could still allow for interactivity, but for the reasons …

  • we wanted to see if highlighting text within a textarea could be achieved … Spoiler Alert: yes, it’s possible … as well as
  • textarea elements have a great resizing “native” functionality
  • textarea elements feel far more “the go” when asking for user interactive entry data that can contain linefeeds
  • over time we find more and more use for the textarea attributes value and innerHTML as separately useful dual ways of populating the element, especially in the scenario with text data where the latter is useful to initiate with text data containing < and > which gets mapped to &lt; and &gt; respectively once the code looks at that textarea‘s value attribute … Cute, huh?! In fairness, though div contenteditable=true also have interesting interplay with innerHTML and innerText attributes going on in this respect too.

… we’re carrying on with textarea element interactive entry usage with this current suite of CSS based web applications.

Here’s the new Javascript function crucial to making this possible …


function divoverlayclone(ovid, indefst) {
var tih='', taih=document.getElementById('divhost').innerHTML, nextih='', tbit='', huhs=[], ihuh=0, mss='', ahh=[], ione=1, ihh=0;
var tarectis=document.getElementById('taidea').getBoundingClientRect();
if (ovid == '') { ovid='doverlay'; } else {
mss=ovid.replace('doverlay','');
for (var iou=0; iou<eval('' + mss); iou++) {
ahh.push('');
}
}
var defclass=(' ' + mss).slice(-1).trim();
for (var itih=taih.indexOf('<'); itih<taih.length; itih++) {
if (taih.substring(itih).substring(0,1) == String.fromCharCode(10)) {
tih+='<br>';
} else if (taih.substring(itih).substring(0,1) == '<') {
tih+='<';
} else if (taih.substring(itih).substring(0,1) == '>') {
tih+='>';
} else {
tih+=taih.substring(itih).substring(0,1);
}
}
document.getElementById(ovid).style.position='absolute';
document.getElementById(ovid).style.top='' + tarectis.top + 'px';
document.getElementById(ovid).style.left='' + tarectis.left + 'px';
document.getElementById(ovid).style.width='' + tarectis.width + 'px';
document.getElementById(ovid).style.height='' + tarectis.height + 'px';
document.getElementById(ovid).style.fontSize = window.getComputedStyle(document.getElementById('taidea'),null).fontSize || document.getElementById('taidea').style.fontSize || document.getElementById('taidea').currentStyle.getCurrentProperty('font-size');
if (indefst.trim() != '') {
//alert('0:' + indefst);
if (document.getElementById('divhost').innerHTML.indexOf(indefst.replace(':',': ')) != -1) {
//alert('00:' + indefst);
if (tih.indexOf(indefst.replace(':',': ') + '">') != -1) {
document.getElementById(ovid).innerHTML=tih.replace(indefst.replace(':',': ') + '">', '<span id=myspan' + mss + ' class=highlight' + (' ' + mss).slice(-1).trim() + ' title="' + indefst.replace(':',': ') + '">' + indefst.replace(':',': ') + '</span>">');
} else {
document.getElementById(ovid).innerHTML=tih.replace(indefst.replace(':',': '), '<span id=myspan' + mss + ' class=highlight' + (' ' + mss).slice(-1).trim() + ' title="' + indefst.replace(':',': ') + '">' + indefst.replace(':',': ') + '</span>');
}
} else if (document.getElementById('divhost').innerHTML.indexOf(indefst) != -1) {
//alert('000:' + indefst);
if (tih.indexOf(indefst + '">') != -1) {
document.getElementById(ovid).innerHTML=tih.replace(indefst + '">', '<span id=myspan' + mss + ' class=highlight' + (' ' + mss).slice(-1).trim() + ' title="' + indefst + '">' + indefst + '</span>">');
} else {
document.getElementById(ovid).innerHTML=tih.replace(indefst, '<span id=myspan' + mss + ' class=highlight' + (' ' + mss).slice(-1).trim() + ' title="' + indefst + '">' + indefst + '</span>');
}
} else {
return '';
}
} else {
//alert(defst);
if (defst.indexOf(';') == -1) {
huhs=defst.split(' ');
//alert('2:' + huhs[0]);
for (ihuh=0; ihuh<huhs.length; ihuh++) {
if (document.getElementById('mysel').innerHTML.indexOf(' value="' + huhs[ihuh] + '">') != -1) {
//alert('3:' + huhs[0]);
tbit+=document.getElementById('mysel').innerHTML.split(' value="' + huhs[ihuh] + '">')[1].split('<')[0];
ahh.push('doverlay' + ione + '~' + document.getElementById('mysel').innerHTML.split(' value="' + huhs[ihuh] + '">')[1].split('<')[0]);
ione++;
}
}
defclass='' + ahh.length;
//alert('defclass=' + defclass);
document.getElementById(ovid).innerHTML=tih.replace(defst, '<span id=myspan' + mss + ' class=highlight' + defclass + ' title="' + tbit + '">' + defst + '</span>');
} else if (document.getElementById('mysel').innerHTML.indexOf(' value="' + defst + '">') != -1) {
if (eval('' + tih.split(defst).length) > 2) {
ahh.push('doverlay' + ione + '~' + document.getElementById('mysel').innerHTML.split(' value="' + defst + '">')[1].split('<')[0]);
ione++;
defclass='' + ahh.length;
}
document.getElementById(ovid).innerHTML=tih.replace(defst, '<span id=myspan' + mss + ' class=highlight' + defclass + ' title="' + document.getElementById('mysel').innerHTML.split(' value="' + defst + '">')[1].split('<')[0] + '">' + defst + '</span>');
} else {
//alert(defst + ' in? ' + tih);
if (eval('' + tih.split(defst).length) > 2 && 1 == 7) {
ahh.push('doverlay' + ione + '~' + document.getElementById('mysel').innerHTML.split(' value="' + defst + '">')[1].split('<')[0]);
ione++;
defclass='' + ahh.length;
}
document.getElementById(ovid).innerHTML=tih.replace(defst, '<span id=myspan' + mss + ' class=highlight' + defclass + ' title="">' + defst + '</span>');
}
}
if (document.getElementById('myspan' + mss)) {
// document.getElementById('myspan' + mss).className='highlight' + ahh.length;
//alert('mss=' + mss + ' oh=' + document.getElementById('myspan' + mss).outerHTML);
nextih=document.getElementById('myspan' + mss).outerHTML;
tarectis=document.getElementById('myspan' + mss).getBoundingClientRect();
document.getElementById(ovid).style.position='absolute';
document.getElementById(ovid).style.top='' + tarectis.top + 'px';
document.getElementById(ovid).style.left='' + tarectis.left + 'px';
document.getElementById(ovid).style.width='' + tarectis.width + 'px';
document.getElementById(ovid).style.height='' + tarectis.height + 'px';
if (tbit != '') {
document.getElementById(ovid).title=tbit;
} else {
document.getElementById(ovid).title=document.getElementById('myspan' + mss).title;
}
//document.getElementById(ovid).className='highlight' + ahh.length;
document.getElementById(ovid).innerHTML=nextih;
}
if (eval('' + ahh.length) > 0) {
for (ihh=0; ihh<ahh.length; ihh++) {
if (ahh[ihh].trim() != '') {
if (document.getElementById('divhost').innerHTML.replace(/\:\ /g,':').indexOf(ahh[ihh].split('~')[1]) != -1) {
//alert(ahh[ihh]);
divoverlayclone(ahh[ihh].split('~')[0], ahh[ihh].split('~')[1]);
} else {
document.getElementById(ahh[ihh].split('~')[0]).innerHTML='';
}
}
}
}
}

… now in …


Previous relevant CSS Backdrop Filter Recursive Iframe Tutorial is shown below.

CSS Backdrop Filter Recursive Iframe Tutorial

CSS Backdrop Filter Recursive Iframe Tutorial

Today’s blog posting calls on the previous …

  • Image Filter Display Tutorial … and asking the question we had making this tutorial …

    Can the CSS filter property applications to HTML img elements also be applied to any form of “background” anything?

    … with an answer …

  • Sort of … if by “background” we can say “backdrop” to a nested, say, HTML div element, with some wording, in turn hosted by a, say, HTML div element that has a “background” image going on.

    … via CSS properties like …

    backdrop-filter: sepia(100%);

    … usage

Today’s work clones off a clone (using the work of yesterday’s CSS Mask HTML Element Recursive Iframe Tutorial) with a new “how we got there” initial cloned draft web application also shown below.


Previous relevant CSS Mask HTML Element Recursive Iframe Tutorial is shown below.

CSS Mask HTML Element Recursive Iframe Tutorial

CSS Mask HTML Element Recursive Iframe Tutorial

Often concept ideas you have for web applications have so much in common with something you’ve been working on, you’d be pretty foolish to not heed the adage …

  • Don’t let the perfect be the enemy of the good.

    … and one way we find to help here is …

  • “cloning” web applications on the understanding that what they have in common so far outweighs what the differences are that you push ahead, and wait and see what the issues are, after that initial “cloning” (usually) huge saving of development time

With that in mind, today, we’re adding off yesterday’s CSS Background Position Revisit Recursive Iframe Tutorial efforts, a …


Mask an HTML Element via CSS

… clone of it with those “midstream” SMS and email recursive iframe smarts (built in) to create a new “how we got there” initial cloned draft web application also shown below.


Previous relevant CSS Background Position Revisit Recursive Iframe Tutorial is shown below.

CSS Background Position Revisit Recursive Iframe Tutorial

CSS Background Position Revisit Recursive Iframe Tutorial

Onto yesterday’s CSS Background Position Revisit Tutorial, today we’re offering …

  • SMS … or …
  • email

… means of sharing your CSS work, as an interactive user, but on this occasion, we have a big gulf regarding what these two options can achieve, due to data length limits.

  • SMS … just the last styling change is transferred to the recipient as what they see … whereas …
  • email … records all user changes to the blockquote element and presents them to the recipient with the most recent topmost down to the original down the bottom of a stack of HTML iframe elements called recursively

So, what do we mean by “called recursively“? Well, like a linked list, our web application always contains an HTML iframe initially …


<iframe frameborder=0 src='/About_Us.html' id=ifbot style=display:none;width:100%;height:6000px;></iframe>

… down the bottom of it’s body element. The document.body onload event Javascript logic call as per onl(”); now includes


var inta='', startstyle='';
var intas=[];
if (document.URL.indexOf('Cjxi') != -1) {
intas=document.URL.split('Cjxi');
for (var inm=1; inm<intas.length; inm++) {
intas[eval(-1 + inm)]=decodeURIComponent(decodeURIComponent(escape(atob('Cjxi' + intas[inm]))));
}
}
inta=(location.search + ('' + location.hash).replace(/^undefined/g,'').replace(/^null/g,'')).split('taidea' + eqis)[1] ? ourdecodeURIComponent((location.search + ('' + location.hash).replace(/^undefined/g,'').replace(/^null/g,'')).split('taidea' + eqis)[1].split('&')[0]).replace(/\+/g,plus) : '';
if (inta.indexOf('background') == 0) {
startstyle=inta;
inta='';
}
var preint='';
preint=inta.split('blockquote')[0];
if (eval('' + intas.length) == 0) {
intas=(inta + ' ').substring(preint.length).split('<blockquote');
}
var nextinta='';


function onl(altta) {
var outta=inta;
if (altta == '' && eval('' + intas.length) > 1) {
nextinta=inta.replace(preint + intas[0], '');
document.getElementById('hrbot').style.display='block';
if (is64) {
document.getElementById('ifbot').src=document.URL.split('?')[0].split('#')[0] + '?#taidea=' + ourencodeURIComponent(nextinta);
} else {
document.getElementById('ifbot').src=document.URL.split('?')[0].split('#')[0] + '?#taidea=' + encodeURIComponent(nextinta);
}
document.getElementById('ifbot').style.display='block';
inta=preint + intas[0];
outta=inta;
intas=[];
}

if (altta == '' && inta != '') {
if (eval('' + inta.split('repeat;').length) > 1) {
origdefopt=(inta.split('repeat;')[1].split(';')[0].split('"')[0] + ';').replace(/^\;/g,'');
document.getElementById('defopt').innerHTML='Styling idea [' + origdefopt + ']';
defoptit=origdefopt;
}
}
if (altta != '') { outta=altta; }
if (outta == '') {
outta=document.getElementById('divhost').innerHTML;
} else {
document.getElementById('divhost').innerHTML=outta;
document.getElementById('taidea').value=document.getElementById('divhost').innerHTML;
if (altta != '') {
if (eval('' + altta.split('repeat;').length) > 1) {
defoptit=(altta.split('repeat;')[1].split(';')[0].split('"')[0] + ';').replace(/^\;/g,'');
document.getElementById('defopt').innerHTML='Styling idea [' + defoptit + ']';
}
}
}
if (document.getElementById('taidea').value.indexOf(' data-yourown=""') == -1 && document.getElementById('taidea').value.indexOf(' data-yourown="') != -1) {
var newuns=document.getElementById('taidea').value.split(' data-yourown="')[1].split('"')[0].split(';,');
for (var inew=0; inew<newuns.length; inew++) {
if (document.getElementById('mysel').innerHTML.indexOf(newuns[inew].replace(/\;$/g,'') + ';') == -1) {
document.getElementById('mysel').innerHTML+='<option value="' + newuns[inew].replace(/\;$/g,'') + ';">' + newuns[inew].replace(/\;$/g,'') + ';</option>';
}
}
}
if (altta == '') {
if (startstyle != '') {
document.getElementById('divhost').innerHTML=document.getElementById('divhost').innerHTML.replace(document.getElementById('divhost').innerHTML.split(' style="')[1].split('"')[0], startstyle);
document.getElementById('taidea').value=document.getElementById('divhost').innerHTML;
}
sofares=document.getElementById('divhost').innerHTML;
setInterval(keeplooking, 5000);
}
//else if (sofares.indexOf(document.getElementById('divhost').innerHTML) == -1) {
//sofares+=document.getElementById('divhost').innerHTML;
//}
}


function keeplooking() {
if (sofares.indexOf(document.getElementById('divhost').innerHTML) == -1) {
var vs=sofares;
sofares=document.getElementById('divhost').innerHTML + vs;
}
}

… to help make this recursion happen in the changed “second draft” web application also shown below.


Previous relevant CSS Background Position Revisit Tutorial is shown below.

CSS Background Position Revisit Tutorial

CSS Background Position Revisit Tutorial

We are great admirers of HTML and CSS regarding the way multiple background images are possible behind an HTML element.

To get to a multiple background image scenario (or even single ones regarding the basis for this blog posting’s creation), the “Making Of” yesterday’s AlmaLinux Astronomy via PHP and Python PyEphem Revisit Tutorial we thought needed further scrutiny.

It’s the HTML blockquote background image of Nala and Luna of most interest, at least to us. It involved the use of CSS …


background-position-x:right;

… property, for our first time, that we can remember that is.

The blockquote styling did something to our …

  1. background-size:contain;
  2. background-repeat:no-repeat;

… “dynamic duo”, again, property combination, truncating imagery to the right (where Nala and Luna, the stars of the show, were) for the first time we’ve ever seen. We were forced to relook at all the background-position type styling properties, and that’s when we came across background-position-x:right as a way to get “the stars” back into the picture.

From there, we thought it might be good to write a proof of concept textarea based showing of the styling of that blockquote element involved, and allow the user to modify it either …

  • within the textarea element, on tabbing out of it … or via …
  • some set dropdown alternative CSS property suggestions … and in amongst those dropdown options, via …
  • enter user CSS properties of interest

… to see, dynamically, what happens to the WordPress styling conditioned blockquote rendition above the form, to confirm what your CSS would do, using our “first draft” web application also shown below …


Previous relevant AlmaLinux Astronomy via PHP and Python PyEphem Revisit Tutorial is shown below.

AlmaLinux Astronomy via PHP and Python PyEphem Revisit Tutorial

AlmaLinux Astronomy via PHP and Python PyEphem Revisit Tutorial

Further to AlmaLinux Astronomy via PHP and Python PyEphem Tutorial

  • these days RJM Programming is still on AlmaLinux …
  • but on a different IP address and web server to that previous blog posting …
  • but PHP versions have not changed, or not enough to cause any consternation … hence the “relative silence” on our part about it all

… but, even so, “things can go wrong”, and on a revisit to our Astronomy web application “things went wrong” …

Who’d have thought it?!

One of the potential issues was resolved with Code Difference AlmaLinux New Webserver Issue Tutorial allowing for exec and shell_exec usage, for which we thank our web hosters, Crazy Domains. There are other players in this astronomy web application though, they being …

  • Python … called via PHP exec … calling …
  • PyEphem module (most importantly)

… and the investigation should start at Python to our mind. Our initial investigation into ephem_astronomy.php code first looking for a path through to Python at …


/usr/bin/python

… and we saw the difference in Terminal sessions asking three things of our two web servers …

Web server The ask … The result is …
Old which python /bin/python
New which python /usr/bin/which: no python in ([new web server’s path for root account])
Old which python3 /bin/python3
New which python3 /bin/python3
Old ls -la /usr/bin/python*
lrwxrwxrwx 1 root root 9 Mar 12 03:06 /usr/bin/python -> ./python3
lrwxrwxrwx 1 root root 9 Mar 12 03:00 /usr/bin/python3 -> python3.9
-rwxr-xr-x 1 root root 15624 Mar 12 03:00 /usr/bin/python3.9
-rwxr-xr-x 1 root root 61 Mar 12 03:00 /usr/bin/python3.9-config
-rwxr-xr-x 1 root root 3624 Mar 12 02:53 /usr/bin/python3.9-x86_64-config
lrwxrwxrwx 1 root root 16 Mar 12 03:00 /usr/bin/python3-config -> python3.9-config
-rwxr-xr-x 1 root root 980 Mar 26 2022 /usr/bin/python3-html2text
lrwxrwxrwx 1 root root 16 Mar 12 03:00 /usr/bin/python-config -> ./python3-config
lrwxrwxrwx 1 root root 17 Mar 26 2022 /usr/bin/python-html2text -> python3-html2text
New ls -la /usr/bin/python*
lrwxrwxrwx 1 root root 16 Mar 12 03:00 /usr/bin/python-config -> ./python3-config
lrwxrwxrwx 1 root root 17 Mar 26 2022 /usr/bin/python-html2text -> python3-html2text
lrwxrwxrwx 1 root root 9 Mar 12 03:00 /usr/bin/python3 -> python3.9
lrwxrwxrwx 1 root root 16 Mar 12 03:00 /usr/bin/python3-config -> python3.9-config
-rwxr-xr-x 1 root root 980 Mar 26 2022 /usr/bin/python3-html2text
-rwxr-xr-x 1 root root 15624 Mar 12 03:00 /usr/bin/python3.9
-rwxr-xr-x 1 root root 61 Mar 12 03:00 /usr/bin/python3.9-config
-rwxr-xr-x 1 root root 3624 Mar 12 02:53 /usr/bin/python3.9-x86_64-config

… and so, after doing the research regarding our question …

On linux is there a better way out of alias versus soft link to solve a path based issue?

… giving the Google AI Overview, thanks, answer …

For solving path-based issues in Linux, symbolic links are generally better than aliases. Aliases are shell-specific and don’t offer the same level of system-wide functionality as symbolic links. Symbolic links, or symlinks, act as references to files or directories within the file system, making them a more robust and versatile solution for path-related problems.

… we think points to Equivalent of alias for a symbolic link and fitting in with our preferences, too, getting us in Terminal on the new web server to go …


$ cd /usr/bin
$ ln -s ./python3.9 ./python

… to end up with …


$ ls -la /usr/bin/python*
lrwxrwxrwx 1 root root 11 Jun 18 07:54 /usr/bin/python -> ./python3.9
lrwxrwxrwx 1 root root 16 Mar 12 03:00 /usr/bin/python-config -> ./python3-config
lrwxrwxrwx 1 root root 17 Mar 26 2022 /usr/bin/python-html2text -> python3-html2text
lrwxrwxrwx 1 root root 9 Mar 12 03:00 /usr/bin/python3 -> python3.9
lrwxrwxrwx 1 root root 16 Mar 12 03:00 /usr/bin/python3-config -> python3.9-config
-rwxr-xr-x 1 root root 980 Mar 26 2022 /usr/bin/python3-html2text
-rwxr-xr-x 1 root root 15624 Mar 12 03:00 /usr/bin/python3.9
-rwxr-xr-x 1 root root 61 Mar 12 03:00 /usr/bin/python3.9-config
-rwxr-xr-x 1 root root 3624 Mar 12 02:53 /usr/bin/python3.9-x86_64-config
$ which python
/bin/python

… and a better functioning Astronomy web application, as well as the chance other PHP calling Python scenarios being fixed, ahead of (web application and PHP and Python code) revisits, there and then. However, if all this sounds trepidacious, or impossible (lots of web hosting would not allow you anywhere close to “underlying Operating System anything”), or your server does not support Soft (ie. Symbolic) Links (eg. Windows) you could change this way the ephem_astronomy.php PHP code to fit with the original environment ahead of creating that new Soft (ie. Symbolic) Link used in that inhouse Astronomy PHP calling Python module web application.


Previous relevant AlmaLinux Astronomy via PHP and Python PyEphem Tutorial is shown below.

AlmaLinux Astronomy via PHP and Python PyEphem Tutorial

AlmaLinux Astronomy via PHP and Python PyEphem Tutorial

You might recall reading the previous PHP/Javascript/HTML and Python PyEphem Moon Angle Tutorial below how we got into some Astronomy via …

  • PHP … calling, via exec
  • Python … (alas, no 3P’s Perl here) … and it’s …
  • PyEphem … module skilled at Astronomy … installed via …
  • Pip … (alas, no Estella)

… so from that … let’s see … we get The Four TopsPipsP’s (in relation to lemon trees … tee hee).

Well, to make Moon Angles and Astronomy Helper web applications work on AlmaLinux we needed to attend to a couple of install matters …

  • install the Python package manager Pip via (the AlmaLinux PHP dnf package manager) …

    dnf install python3-pip.noarch
  • install the Python module, helping out with Astronomy matters, called PyEphem via …

    sudo pip install pyephem

… to be in a position to progress, and then add a check for existence of /usr/bin/python (for AlmaLinux) in preference to /usr/local/bin/python3.3 (for CentOS) as the final measure needed to start getting results back to any PHP overseers …


Previous relevant PHP/Javascript/HTML and Python PyEphem Moon Angle Tutorial is shown below.

PHP/Javascript/HTML and Python PyEphem Moon Angle Tutorial

PHP/Javascript/HTML and Python PyEphem Moon Angle Tutorial

A long time ago now we presented PHP/Javascript/HTML Moon Angle Tutorial but now we feel is a good time for it to get a makeover. Why is that? Well, we have the relatively new discovery of the very useful Python PyEphem module to thank for that.

As far as the new version goes we now offer a Moon Angle “time of transit (and relative to now)” calculation, which we think will be of more use to users.

The Moon Angle at Transit calculations again involve the Sublunary Point as the position on Earth directly above which is Moon is located. Add in the Python PyEphem work and some more terminology that may interest you could involve …

… within the Python of interest, a snapshot of which is shown below, but which changes each time somebody recreates this sublunarx.py


import ephem
import math
import time
from datetime import datetime, timedelta
greenwich = ephem.Observer()
greenwich.lat = "0"
greenwich.lon = "0"
greenwich.date = datetime.utcnow()
moon = ephem.Moon(greenwich)
moon.compute(greenwich.date)
moon_lon = math.degrees(moon.ra - greenwich.sidereal_time() )
if moon_lon < -180.0 :
moon_lon = 360.0 + moon_lon
elif moon_lon > 180.0 :
moon_lon = moon_lon - 360.0
moon_lat = math.degrees(moon.dec)
d1 = ephem.next_full_moon(greenwich.date)
d2 = ephem.next_new_moon(greenwich.date)
greenwich.lat = "151:10.586502000000001"
greenwich.lon = "-33:54.445878"
greenwich.date = datetime.utcnow()
moon = ephem.Moon(greenwich)
moon.compute(greenwich.date)
betw = (greenwich.next_transit(moon) - greenwich.date) * 86400.0 / 60.0 / 60.0
gnt = greenwich.next_transit(moon)
greenwich.date = gnt
moon = ephem.Moon(greenwich)
moon.compute(gnt)
moon_lon_x = math.degrees(moon.ra - greenwich.sidereal_time() )
if moon_lon_x < -180.0 :
moon_lon_x = 360.0 + moon_lon_x
elif moon_lon_x > 180.0 :
moon_lon_x = moon_lon_x - 360.0
moon_lat_y = math.degrees(moon.dec)
print('%s %s %s %s %s %s %s %f' % (moon_lon, moon_lat, d1, d2, gnt, moon_lon_x, moon_lat_y, betw))
quit()

The Moon Angle web application live run, which we welcome you to try, has the underlying PHP moon_angle_now_at.php that supervises the Python exemplied above, and which featured these changes to make this happen.


Previous relevant PHP/Javascript/HTML Moon Angle Tutorial is shown below.

PHP/Javascript/HTML Moon Angle Tutorial

PHP/Javascript/HTML Moon Angle Tutorial

Here is a tutorial that calculates Noon Moon Angles from Earth via the entry of Latitude and Longitude. The calculation of noon moon angles uses the concept of Sublunary Point, which is explained in the quote from Wikipedia below.

The sublunary point (Latin sub-lunar, under the moon ‘, from Latin) is the one place on earth where the moon in exactly the zenith is. He is the point where the line connecting the centers of the Earth and Moon intersects the Earth’s surface. The point is a common auxiliary point to observe the Moon in the celestial mechanics and astronomical phenomenology , and in particular the theory of the tides , as well as the theory of eclipses .

The calculation of the point corresponding to the determination of the geocentric coordinates of the Moon, it has the same longitude and latitude , as the moon astronomical length and width has – both are denoted by φ and β.

The Javascript embellishments in this tutorial mainly revolve around:

The use of window.open can sometimes be blocked by web browsers depending on their settings and you can read a bit more about such issues here.

Useful tutorials that helped, and we give thanks to, were:

Here is a link to a live run. (The way it changed on 1/12/2013 to have a dropdown of placenames as extra functionality will be explained in a tutorial called PHP/Javascript/HTML Geographical Placename Integration Tutorial on 3/12/2013.)

Here is a link to some downloadable PHP programming source code which you may want to rename to moon_angle_now_at.php

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

Posted in eLearning, Event-Driven Programming, Tutorials | Tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , | Leave a comment