Udostępniam książkę redagowaną przez prof. A. Walczaka o programowaniu w C++
Dzwoni klient i mówi:
- “Witam serdecznie, przesyłam panu maila i chciałbym mieć możliwość wstawiana skomplikowanych równań matematycznych na swoją strunę, czy mógłby Pan zrobić coś takiego” – mówi z wielkim przejęciem “kustomer”
- “Witam, już chwileczkę odbiorę pocztę” – z niecieprliwieniem czekam co ukaże się moim oczom, i co widzę :

Latex
Moim oczom ukazało się ogromne równanie matematyczne gdzie rozwiązaniem było 1.
- “Na pewno się da tylko muszę zapoznać się z problemem” – odpowiedziałem nieśmiało.
Po rozeznaniu tematu miałem do wyboru albo skorzystać z MathML który nie jest wspierany przez wszystkie przeglądarki, lub latex renderowanie z języka latexowego do obrazka. Wybrałem drugie rozwiązanie. LaTeX to oprogramowanie do zautomatyzowanego składu tekstu, a także związany z nim język znaczników, służący do formatowania dokumentów tekstowych i tekstowo-graficznych (na przykład: broszur, artykułów, książek, plakatów, a nawet stron HTML). (źródło wiki: http://pl.wikipedia.org/wiki/LaTeX) Rozpisywać się zbytnio więcej nie będę gdyż doczytać możecie na stronie wiki.
Do przetworzenia równania matematycznego z pseudojęzyka do obrazka potrzebujemy bibliotek latex oraz dvipng, wynika to z tego jak długa droga musi zostać przebyta, wizualizuje to poniższy obrazek.
Aby wygenerować [tex]\sqrt(x)[/tex] z tego obrazek nalezy wykonać stworzyć wstępnie szablon latex:
\documentclass[11pt]{article}
\usepackage{amsmath}
\usepackage{helvet}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{pst-plot}
\usepackage{color}
\pagestyle{empty}
\begin{document}
\sqrt(x)
\end{document}
Następnie tworzymy plik div ktory będzie podstawa do wygenerowania pliku PNG
latex --interaction=nonstopmode rownanie.tex
A teraz obrazek:
dvipng -T tight rownanie.dvi -o rownanie.png
No to do dzieła, piszemy heleprek do obsługi tego wszytkiego.
class Inicio_Controller_Action_Helper_Latex extends Zend_Controller_Action_Helper_Abstract
{
var $LATEX_PATH = "latex";
var $CONVERT_PATH = "dvipng";
var $TMP_DIR = '/temp';
var $CACHE_DIR = '/images';
Określamy polecenia systemowe, oraz miejsce tymczasowe gdzie będa generowanie pliki aux, div i inne pomocine do wygenerowania pliku png
private function wrap($thunk) {
return
"\documentclass[11pt]{article}
\usepackage{amsmath}
\usepackage{helvet}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{pst-plot}
\usepackage{color}
\pagestyle{empty}
\begin{document}
$thunk
\end{document}";
}
Opakowywujemy nasze równanie w szablon
private function render_latex($thunk, $hash)
{
$thunk = $this->wrap($thunk);
$current_dir = getcwd();
chdir($this->TMP_DIR);
// create temporary LaTeX file
$fp = fopen($this->TMP_DIR . "/$hash.tex", "w+");
fputs($fp, $thunk);
fclose($fp);
$command = $this->LATEX_PATH . " --interaction=nonstopmode " . $hash . ".tex";
exec($command);
$command = $this->CONVERT_PATH . " -T tight $hash.dvi -o $hash.png";
exec($command, $r);
if(is_file($this->TMP_DIR.'/'.$hash.'.png'))
{
copy("$hash.png", $this->CACHE_DIR . "/$hash.png");
}
else
{
throw new Exception('Nie wyrenderowano pliku');
}
chdir($current_dir);
}
Renderujemy obrazek
private function cleanup($hash) {
$current_dir = getcwd();
chdir($this->TMP_DIR);
unlink($this->TMP_DIR . "/$hash.tex");
unlink($this->TMP_DIR . "/$hash.aux");
unlink($this->TMP_DIR . "/$hash.log");
unlink($this->TMP_DIR . "/$hash.dvi");
unlink($this->TMP_DIR . "/$hash.png");
chdir($current_dir);
}
Czyścimy śmiecie
function transform($text)
{
$thunk = $text;
$hash = md5($text);
$full_name = $this->CACHE_DIR . "/" . $hash . ".png";
if (!is_file($full_name)) {
$this->render_latex($thunk, $hash);
$this->cleanup($hash);
}
ob_end_clean();
header('Content-Type: image/png');
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.filesize($full_name));
@readfile($full_name);
exit;
}
Zmiana textu na obrazek.
Dla bardziej zainteresowanych tematem polecam biblioteke JS do generowania równań matematycznych: http://www.math.union.edu/~dpvc/jsMath/
Niedawno zaznajamiałem się z problemem obsługi map i nanoszenia na nie warstwy vektorowe, WMS, Markerów itp. Problem polegał na tym by móc w jednym momencie zmieniać sobie mapy Google Maps, Yahoo Maps, końcówki map MapServer itp. Najlepszym rozwiązaniem jakie znalazłem w internecie to tytułowy OpenLayers.
Openlayers to szeroko rozumiana biblioteka napisana w JS do obsługi map – możemy w banalny sposób nanosić na siebie wartwy różnego formatu nie przejmując się o jakiekolwiek konflikty. Dla przykładu zaprezentuje sposób wykorzystania dwóch dostawców map Google Maps oraz UMP:
var options = {
controls: [
new OpenLayers.Control.Navigation(),
new OpenLayers.Control.PanZoomBar(),
new OpenLayers.Control.LayerSwitcher({'ascending':false}),
new OpenLayers.Control.MousePosition(),
],
maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
maxResolution: 156543.0399,
numZoomLevels: 19,
units: 'm',
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326")
};
map = new OpenLayers.Map('map', options);
initLanguage();
var google = new OpenLayers.Layer.Google( "Google Hybrid" , {numZoomLevels: 20, 'sphericalMercator': true});
var osm = new OpenLayers.Layer.OSM("UMP@Mapnik",
[
"http://1.tiles.ump.waw.pl/ump_tiles/",
"http://2.tiles.ump.waw.pl/ump_tiles/",
"http://3.tiles.ump.waw.pl/ump_tiles/"
],
{numZoomLevels: 19, 'buffer':0,
attribution: "Data by UMP-pcPL
"});
map.addLayers([google, osm ]);
W ten oto sposób można na obiekcie DOM #map utworzyć pole z mapami Google i UMP. Wykorzystajmy odwzorowanie kartograficzne: EPSG:4326 dla dokładnego pokazywania loklizacji z LatLong.
controls: [
new OpenLayers.Control.Navigation(),
new OpenLayers.Control.PanZoomBar(),
new OpenLayers.Control.LayerSwitcher({'ascending':false}),
new OpenLayers.Control.MousePosition(),
]
Odpowaida za dodanie odpowiednich kontrolerów mapy, nawigacja, pasek do zoomowania mapy, zmiana warstw, zmiana pozycji mapy za pomocą myszy.
Wykorzystując dobroć języka PHP i jego (nie)banalnej obiektowości może byśmy tak zrobili takie coś co pomoże nam w budowie przyszłych serwisów, aplikacji webowych i im pochodnych – zwane frameworkiem, czyli ramą systemu na której powstaje przyszła budowa.
Wykorzystamy do tego znany wzorzec obiektowy MVC (model- view-controller), gdzie wszytko mamy ładnie oddzielone od siebie.
Model jest odzwierciedleniem bazy danych
View – warstwa prezentacji
Controller – warstwa logiczna
Ważnym elementem jest to aby nasz przyszły framework był zbudowany modułowo, np.: core, newsletter, page itp.
Tak więc zabieramy się za strukturę katalogów naszego framework, oczywiście nie musi to być tak jak to ja zaproponuje ale wydaje mi się ze to godna reprezentacja (wzorowana na zend framework)
inicio_framework
|- application
|- config
|- interface
|- public
|- layouts
|- mails
|- modules
|- exampleModule
|- controllers
|- views
|- scripts
|- index
|- admin
|- models
|- temp
|- cache
|- captcha
|- doc
|- library
| |- Inicio
|- upload
|- web_public
|- web_admin
Nastała ta chwila aby wyjaśnić niektórym osobom gdzie co bym widział. Idąc od góry. Katalog application zawierać będzie całe ciało aplikacji, zmieniając jakiekolwiek pliki biblioteki nie będziemy ingerować w naszą aplikacje. Aplikacja musi być łątwo konfigurowala tak więc potrzeny nam jest katalog w którym zawierać się bedą pliki zapisane w formacie ini. Każda aplikacja posiadać będzie dwa interfejsy publiczny oraz administracyjny inaczej zwane frontend oraz backedn. Jeśli mamy w zamiarze napisać dużą aplikację która wymagać będzie dużej ingerencji administracji niedostępnej dla zwykłego użytkownika najlepiej przenieść wszytko do “backendu”.
Każdy z interfejsów zawiera swoje layouty, czyli główną skórkę, szablony maili, oraz najważniejsze: moduły. W planie mamy napisanie frameworku modułowego czyli dokładanie kolejnych klocków do aplikacji które nie rozwalą nam całości, a dokładanie kolejnych modułów nie będzie wymagać od nas poprawianie wcześniej napisanego kodu. Każdy moduł posiada swoje skórki zgromadzone w katalogu views.
– EDIT
Wychodzimy do katalogu application – tam znajdujemy models, czyli serowanie danych do warstwy controlera (dane z bazy danych, dane z google api itp) np User.php oraz Users.php (kolekcja obiektów typu User) ale to wyjaśnimy w dalszej częsci krok po kroku ![]()
– END EDIT
Katalog temp zawierac będzie głównie cache oraz pomocnicze pliki.
Głównym sercem aplikacji będzie library oprzemy to o własne klasy oraz wspomożemy się troszkę ZF który posiada dużo ciekawych rozwiązań.
Web_public zawierać będzie plik index.php który będzie opalał całą aplikację interfejsu publicznego natomiast w web_public będzie sturup wersji administracyjnej oraz wszytkie pomocnicze pliki css, js.
Czasem potrzebujemy ile został przesunięty scroll w dół, choćby nawet do tego żeby utrzymać jakiegoś diva cały czas na górze okna przeglądarki (przesuwając scrolla)
$(window).scrollTop()
Tablica encji html’owych: http://www.digitalmediaminute.com/reference/entity/index.php
Wizualizacja tabel, wyniki na canvasach.
XPM – projekty o wysokim stopniu ryzyka, praca w 2, refactoring kodu, dialog, komunikacja, prostota, sprzerzenia zwrotne http://www.truesolutions.pl/blog/podstawy-i-wartosci-extreme-programming-xp-cz-1
PRINCE2 – określone rozpoczęcie i zakończenie, definicja zakończenia projektu, określona pula zasobów, okreslone działania biznesowe, okreslenie obowiązków
PERT – definiowana za pomoca diagramu sieciowego, wierzchołki zadaniami łuki czas zadania, czas trwania jest ściśle losowy
Jak szybko mając date w formacie Y-m-d H:i zrobić z niej d.m.Y ?
date_format(date_create($save_date), 'd.m.Y');
Ostatnie komentarze