diff --git a/README.md b/README.md index 7f7be89..82f8ca6 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,33 @@ -# preposter.us +###Why### +When Posterous was created, it was perfect. + +Over time it became bloated, but it's heart was still in the right place. Then it died. + +Preposter.us is an attempt to ressurect the heart of Posterous, in under 500 lines of Python. + +###Status### +Visit http://jason.gullickson.preposter.us/ To follow along with Preposter.us's development and testing. + +###How it works### +To start a new blog, send a post via email to preposter.us's email address. Preposter.us will read the email, create a new blog and post your initial entry. When you want to create a new post, send another email. To edit/update an existing post, send another email with a subject line that is identical to the title of the post you want to update. To delete a post, send an email with an identical title that contains no text in the body. + +More detailed instructions for using Preposter.us can be found here: http://jason.gullickson.preposter.us/how-to-use-preposterous-1-0.html + +Preposter.us maintains an index of all bloggers using each server, and generates an index for the posts in each blog as well. Blogs are identified by the email address used to post, so to create additional blogs, just submit a post from a different email address. + +Anything that can send an email can publish via Preposter.us. + +###Requirements### +Preposter.us requires Python (tested with 2.7, but probably works with any 2.x version), and a webserver that can serve static HTML; thats all. No database, no external libraries, nada. + +###Useage### +To setup a Preposter.us server, start by setting up an email address that the server will listen to (an address you'll be sending posts to), free gmail addresses work great for this. + +Next clone this repository and copy preposter.us.cfg.template to preposter.us.cfg. Using your favorite editor, open preposter.us.cfg, theres a couple configuration variables you'll need to setup for your site. + +Once the script is configured, send a post to the email address you setup above and then run the preposter.us.py script. If all goes well it will return silently, and you should have a new directory where you specified the web root to be. If the script returns an error, or doesn't create a new blog directory, review the Issues list here to see if you're experiencing a known issue. If not, and if you don't know what else to do, post a new Issue here with details on your setup and how to recreate the error. + +If all goes well the next step is to expose your blog files to the web. The files generated by Preposter.us are simple HTML and can be served using any webserver (or even viewed directly in a browser). Finally, setup a cron job to run preposter.us.py on a scheduled basis to automatically post new blog entries whenever they come into the mailbox. + +If you just want to *use* Preposter.us but don't want to run your own server email your first post to "post at preposter.us". -Future home of preposter.us \ No newline at end of file diff --git a/css/florsn01-demo.html b/css/florsn01-demo.html new file mode 100644 index 0000000..b405d49 --- /dev/null +++ b/css/florsn01-demo.html @@ -0,0 +1,609 @@ + + + + + + + + + + + + + Florencesans Regular Specimen + + + + + + +
+ + + +
+ + +
+ +
+
+
AaBb
+
+
+ +
+
A​B​C​D​E​F​G​H​I​J​K​L​M​N​O​P​Q​R​S​T​U​V​W​X​Y​Z​a​b​c​d​e​f​g​h​i​j​k​l​m​n​o​p​q​r​s​t​u​v​w​x​y​z​1​2​3​4​5​6​7​8​9​0​&​.​,​?​!​@​(​)​#​$​%​*​+​-​=​:​;
+
+
+
+ + + + + + + + + + + + + + + + +
10abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
11abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
12abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
13abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
14abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
16abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
18abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
20abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
24abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
30abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
36abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
48abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
60abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
72abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
90abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
+ +
+ +
+ + + +
+ + +
+
◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼body
body
body
body
+
+ bodyFlorencesans Regular +
+
+ bodyArial +
+
+ bodyVerdana +
+
+ bodyGeorgia +
+ + + +
+ + +
+ +
+

10.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

11.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

12.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

13.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+ +
+
+
+

14.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

16.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

18.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+ +
+ +
+ +
+
+

20.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+

24.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+ +
+ +
+ +
+
+

30.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+ +
+ + + +
+
+

10.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

11.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

12.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

13.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+ +
+ +
+
+

14.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

16.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

18.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+ +
+ +
+
+

20.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+

24.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+ +
+ +
+ +
+
+

30.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+ +
+ + + + +
+ +
+ +
+ +
+

Lorem Ipsum Dolor

+

Etiam porta sem malesuada magna mollis euismod

+ + +
+
+
+
+

Donec sed odio dui. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.

+ + +

Pellentesque ornare sem

+ +

Maecenas sed diam eget risus varius blandit sit amet non magna. Maecenas faucibus mollis interdum. Donec ullamcorper nulla non metus auctor fringilla. Nullam id dolor id nibh ultricies vehicula ut id elit. Nullam id dolor id nibh ultricies vehicula ut id elit.

+ +

Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.

+ +

Nulla vitae elit libero, a pharetra augue. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean lacinia bibendum nulla sed consectetur.

+ +

Nullam quis risus eget urna mollis ornare vel eu leo. Nullam quis risus eget urna mollis ornare vel eu leo. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec ullamcorper nulla non metus auctor fringilla.

+ +

Cras mattis consectetur

+ +

Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Aenean lacinia bibendum nulla sed consectetur. Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Cras mattis consectetur purus sit amet fermentum.

+ +

Nullam id dolor id nibh ultricies vehicula ut id elit. Nullam quis risus eget urna mollis ornare vel eu leo. Cras mattis consectetur purus sit amet fermentum.

+
+ + +
+ +
+ + + + + + +
+
+
+ +

Language Support

+

The subset of Florencesans Regular in this kit supports the following languages:
+ + Albanian, Basque, Breton, Chamorro, Danish, Dutch, English, Faroese, Finnish, French, Frisian, Galician, German, Icelandic, Italian, Malagasy, Norwegian, Portuguese, Spanish, Swedish

+

Glyph Chart

+

The subset of Florencesans Regular in this kit includes all the glyphs listed below. Unicode entities are included above each glyph to help you insert individual characters into your layout.

+
+ +



+

 

+

!

!
+

"

"
+

#

#
+

$

$
+

%

%
+

&

&
+

'

'
+

(

(
+

)

)
+

*

*
+

+

+
+

,

,
+

-

-
+

.

.
+

/

/
+

0

0
+

1

1
+

2

2
+

3

3
+

4

4
+

5

5
+

6

6
+

7

7
+

8

8
+

9

9
+

:

:
+

&#59;

;
+

<

<
+

&#61;

=
+

&#62;

>
+

&#63;

?
+

&#64;

@
+

&#65;

A
+

&#66;

B
+

&#67;

C
+

&#68;

D
+

&#69;

E
+

&#70;

F
+

&#71;

G
+

&#72;

H
+

&#73;

I
+

&#74;

J
+

&#75;

K
+

&#76;

L
+

&#77;

M
+

&#78;

N
+

&#79;

O
+

&#80;

P
+

&#81;

Q
+

&#82;

R
+

&#83;

S
+

&#84;

T
+

&#85;

U
+

&#86;

V
+

&#87;

W
+

&#88;

X
+

&#89;

Y
+

&#90;

Z
+

&#91;

[
+

&#92;

\
+

&#93;

]
+

&#94;

^
+

&#95;

_
+

&#96;

`
+

&#97;

a
+

&#98;

b
+

&#99;

c
+

&#100;

d
+

&#101;

e
+

&#102;

f
+

&#103;

g
+

&#104;

h
+

&#105;

i
+

&#106;

j
+

&#107;

k
+

&#108;

l
+

&#109;

m
+

&#110;

n
+

&#111;

o
+

&#112;

p
+

&#113;

q
+

&#114;

r
+

&#115;

s
+

&#116;

t
+

&#117;

u
+

&#118;

v
+

&#119;

w
+

&#120;

x
+

&#121;

y
+

&#122;

z
+

&#123;

{
+

&#124;

|
+

&#125;

}
+

&#126;

~
+

&#160;

 
+

&#161;

¡
+

&#162;

¢
+

&#163;

£
+

&#164;

¤
+

&#165;

¥
+

&#166;

¦
+

&#167;

§
+

&#168;

¨
+

&#169;

©
+

&#170;

ª
+

&#171;

«
+

&#172;

¬
+

&#173;

­
+

&#174;

®
+

&#175;

¯
+

&#176;

°
+

&#177;

±
+

&#178;

²
+

&#179;

³
+

&#180;

´
+

&#182;

+

&#183;

·
+

&#184;

¸
+

&#185;

¹
+

&#186;

º
+

&#187;

»
+

&#188;

¼
+

&#189;

½
+

&#190;

¾
+

&#191;

¿
+

&#192;

À
+

&#193;

Á
+

&#194;

Â
+

&#195;

Ã
+

&#196;

Ä
+

&#197;

Å
+

&#198;

Æ
+

&#199;

Ç
+

&#200;

È
+

&#201;

É
+

&#202;

Ê
+

&#203;

Ë
+

&#204;

Ì
+

&#205;

Í
+

&#206;

Î
+

&#207;

Ï
+

&#208;

Ð
+

&#209;

Ñ
+

&#210;

Ò
+

&#211;

Ó
+

&#212;

Ô
+

&#213;

Õ
+

&#214;

Ö
+

&#215;

×
+

&#216;

Ø
+

&#217;

Ù
+

&#218;

Ú
+

&#219;

Û
+

&#220;

Ü
+

&#221;

Ý
+

&#222;

Þ
+

&#223;

ß
+

&#224;

à
+

&#225;

á
+

&#226;

â
+

&#227;

ã
+

&#228;

ä
+

&#229;

å
+

&#230;

æ
+

&#231;

ç
+

&#232;

è
+

&#233;

é
+

&#234;

ê
+

&#235;

ë
+

&#236;

ì
+

&#237;

í
+

&#238;

î
+

&#239;

ï
+

&#240;

ð
+

&#241;

ñ
+

&#242;

ò
+

&#243;

ó
+

&#244;

ô
+

&#245;

õ
+

&#246;

ö
+

&#247;

÷
+

&#248;

ø
+

&#249;

ù
+

&#250;

ú
+

&#251;

û
+

&#252;

ü
+

&#253;

ý
+

&#254;

þ
+

&#255;

ÿ
+

&#338;

Œ
+

&#339;

œ
+

&#376;

Ÿ
+

&#710;

ˆ
+

&#732;

˜
+

&#8192;

 
+

&#8193;

+

&#8194;

+

&#8195;

+

&#8196;

+

&#8197;

+

&#8198;

+

&#8199;

+

&#8200;

+

&#8201;

+

&#8202;

+

&#8208;

+

&#8209;

+

&#8210;

+

&#8211;

+

&#8212;

+

&#8216;

+

&#8217;

+

&#8218;

+

&#8220;

+

&#8221;

+

&#8222;

+

&#8226;

+

&#8230;

+

&#8239;

+

&#8249;

+

&#8250;

+

&#8287;

+

&#8364;

+

&#8482;

+

&#9724;

+
+
+ + +
+
+ + +
+ +
+ +
+
+
+

Installing Webfonts

+ +

Webfonts are supported by all major browser platforms but not all in the same way. There are currently four different font formats that must be included in order to target all browsers. This includes TTF, WOFF, EOT and SVG.

+ +

1. Upload your webfonts

+

You must upload your webfont kit to your website. They should be in or near the same directory as your CSS files.

+ +

2. Include the webfont stylesheet

+

A special CSS @font-face declaration helps the various browsers select the appropriate font it needs without causing you a bunch of headaches. Learn more about this syntax by reading the Fontspring blog post about it. The code for it is as follows:

+ + + +@font-face{ + font-family: 'MyWebFont'; + src: url('WebFont.eot'); + src: url('WebFont.eot?#iefix') format('embedded-opentype'), + url('WebFont.woff') format('woff'), + url('WebFont.ttf') format('truetype'), + url('WebFont.svg#webfont') format('svg'); +} + + +

We've already gone ahead and generated the code for you. All you have to do is link to the stylesheet in your HTML, like this:

+ <link rel="stylesheet" href="stylesheet.css" type="text/css" charset="utf-8" /> + +

3. Modify your own stylesheet

+

To take advantage of your new fonts, you must tell your stylesheet to use them. Look at the original @font-face declaration above and find the property called "font-family." The name linked there will be what you use to reference the font. Prepend that webfont name to the font stack in the "font-family" property, inside the selector you want to change. For example:

+p { font-family: 'WebFont', Arial, sans-serif; } + +

4. Test

+

Getting webfonts to work cross-browser can be tricky. Use the information in the sidebar to help you if you find that fonts aren't loading in a particular browser.

+
+ + +
+ +
+ +
+ +
+ + diff --git a/css/florsn01-webfont.eot b/css/florsn01-webfont.eot new file mode 100644 index 0000000..61463a7 Binary files /dev/null and b/css/florsn01-webfont.eot differ diff --git a/css/florsn01-webfont.svg b/css/florsn01-webfont.svg new file mode 100644 index 0000000..9b6162b --- /dev/null +++ b/css/florsn01-webfont.svg @@ -0,0 +1,342 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/css/florsn01-webfont.ttf b/css/florsn01-webfont.ttf new file mode 100644 index 0000000..a3346c3 Binary files /dev/null and b/css/florsn01-webfont.ttf differ diff --git a/css/florsn01-webfont.woff b/css/florsn01-webfont.woff new file mode 100644 index 0000000..fc58b6d Binary files /dev/null and b/css/florsn01-webfont.woff differ diff --git a/css/florsn01-webfont.woff2 b/css/florsn01-webfont.woff2 new file mode 100644 index 0000000..40c5aa1 Binary files /dev/null and b/css/florsn01-webfont.woff2 differ diff --git a/css/florsn41-demo.html b/css/florsn41-demo.html new file mode 100644 index 0000000..c0e0d3e --- /dev/null +++ b/css/florsn41-demo.html @@ -0,0 +1,609 @@ + + + + + + + + + + + + + Florencesans Shaded Regular Specimen + + + + + + +
+ + + +
+ + +
+ +
+
+
AaBb
+
+
+ +
+
A​B​C​D​E​F​G​H​I​J​K​L​M​N​O​P​Q​R​S​T​U​V​W​X​Y​Z​a​b​c​d​e​f​g​h​i​j​k​l​m​n​o​p​q​r​s​t​u​v​w​x​y​z​1​2​3​4​5​6​7​8​9​0​&​.​,​?​!​@​(​)​#​$​%​*​+​-​=​:​;
+
+
+
+ + + + + + + + + + + + + + + + +
10abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
11abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
12abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
13abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
14abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
16abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
18abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
20abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
24abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
30abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
36abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
48abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
60abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
72abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
90abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
+ +
+ +
+ + + +
+ + +
+
◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼body
body
body
body
+
+ bodyFlorencesans Shaded Regular +
+
+ bodyArial +
+
+ bodyVerdana +
+
+ bodyGeorgia +
+ + + +
+ + +
+ +
+

10.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

11.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

12.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

13.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+ +
+
+
+

14.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

16.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

18.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+ +
+ +
+ +
+
+

20.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+

24.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+ +
+ +
+ +
+
+

30.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+ +
+ + + +
+
+

10.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

11.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

12.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

13.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+ +
+ +
+
+

14.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

16.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+

18.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+ +
+
+ +
+ +
+
+

20.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+

24.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+ +
+ +
+ +
+
+

30.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

+
+
+ +
+ + + + +
+ +
+ +
+ +
+

Lorem Ipsum Dolor

+

Etiam porta sem malesuada magna mollis euismod

+ + +
+
+
+
+

Donec sed odio dui. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.

+ + +

Pellentesque ornare sem

+ +

Maecenas sed diam eget risus varius blandit sit amet non magna. Maecenas faucibus mollis interdum. Donec ullamcorper nulla non metus auctor fringilla. Nullam id dolor id nibh ultricies vehicula ut id elit. Nullam id dolor id nibh ultricies vehicula ut id elit.

+ +

Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.

+ +

Nulla vitae elit libero, a pharetra augue. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean lacinia bibendum nulla sed consectetur.

+ +

Nullam quis risus eget urna mollis ornare vel eu leo. Nullam quis risus eget urna mollis ornare vel eu leo. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec ullamcorper nulla non metus auctor fringilla.

+ +

Cras mattis consectetur

+ +

Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Aenean lacinia bibendum nulla sed consectetur. Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Cras mattis consectetur purus sit amet fermentum.

+ +

Nullam id dolor id nibh ultricies vehicula ut id elit. Nullam quis risus eget urna mollis ornare vel eu leo. Cras mattis consectetur purus sit amet fermentum.

+
+ + +
+ +
+ + + + + + +
+
+
+ +

Language Support

+

The subset of Florencesans Shaded Regular in this kit supports the following languages:
+ + Albanian, Basque, Breton, Chamorro, Danish, Dutch, English, Faroese, Finnish, French, Frisian, Galician, German, Icelandic, Italian, Malagasy, Norwegian, Portuguese, Spanish, Swedish

+

Glyph Chart

+

The subset of Florencesans Shaded Regular in this kit includes all the glyphs listed below. Unicode entities are included above each glyph to help you insert individual characters into your layout.

+
+ +

&#13;

+

&#32;

+

&#33;

!
+

&#34;

"
+

&#35;

#
+

&#36;

$
+

&#37;

%
+

&#38;

&
+

&#39;

'
+

&#40;

(
+

&#41;

)
+

&#42;

*
+

&#43;

+
+

&#44;

,
+

&#45;

-
+

&#46;

.
+

&#47;

/
+

&#48;

0
+

&#49;

1
+

&#50;

2
+

&#51;

3
+

&#52;

4
+

&#53;

5
+

&#54;

6
+

&#55;

7
+

&#56;

8
+

&#57;

9
+

&#58;

:
+

&#59;

;
+

&#60;

<
+

&#61;

=
+

&#62;

>
+

&#63;

?
+

&#64;

@
+

&#65;

A
+

&#66;

B
+

&#67;

C
+

&#68;

D
+

&#69;

E
+

&#70;

F
+

&#71;

G
+

&#72;

H
+

&#73;

I
+

&#74;

J
+

&#75;

K
+

&#76;

L
+

&#77;

M
+

&#78;

N
+

&#79;

O
+

&#80;

P
+

&#81;

Q
+

&#82;

R
+

&#83;

S
+

&#84;

T
+

&#85;

U
+

&#86;

V
+

&#87;

W
+

&#88;

X
+

&#89;

Y
+

&#90;

Z
+

&#91;

[
+

&#92;

\
+

&#93;

]
+

&#94;

^
+

&#95;

_
+

&#96;

`
+

&#97;

a
+

&#98;

b
+

&#99;

c
+

&#100;

d
+

&#101;

e
+

&#102;

f
+

&#103;

g
+

&#104;

h
+

&#105;

i
+

&#106;

j
+

&#107;

k
+

&#108;

l
+

&#109;

m
+

&#110;

n
+

&#111;

o
+

&#112;

p
+

&#113;

q
+

&#114;

r
+

&#115;

s
+

&#116;

t
+

&#117;

u
+

&#118;

v
+

&#119;

w
+

&#120;

x
+

&#121;

y
+

&#122;

z
+

&#123;

{
+

&#124;

|
+

&#125;

}
+

&#126;

~
+

&#160;

 
+

&#161;

¡
+

&#162;

¢
+

&#163;

£
+

&#164;

¤
+

&#165;

¥
+

&#166;

¦
+

&#167;

§
+

&#168;

¨
+

&#169;

©
+

&#170;

ª
+

&#171;

«
+

&#172;

¬
+

&#173;

­
+

&#174;

®
+

&#175;

¯
+

&#176;

°
+

&#177;

±
+

&#178;

²
+

&#179;

³
+

&#180;

´
+

&#182;

+

&#183;

·
+

&#184;

¸
+

&#185;

¹
+

&#186;

º
+

&#187;

»
+

&#188;

¼
+

&#189;

½
+

&#190;

¾
+

&#191;

¿
+

&#192;

À
+

&#193;

Á
+

&#194;

Â
+

&#195;

Ã
+

&#196;

Ä
+

&#197;

Å
+

&#198;

Æ
+

&#199;

Ç
+

&#200;

È
+

&#201;

É
+

&#202;

Ê
+

&#203;

Ë
+

&#204;

Ì
+

&#205;

Í
+

&#206;

Î
+

&#207;

Ï
+

&#208;

Ð
+

&#209;

Ñ
+

&#210;

Ò
+

&#211;

Ó
+

&#212;

Ô
+

&#213;

Õ
+

&#214;

Ö
+

&#215;

×
+

&#216;

Ø
+

&#217;

Ù
+

&#218;

Ú
+

&#219;

Û
+

&#220;

Ü
+

&#221;

Ý
+

&#222;

Þ
+

&#223;

ß
+

&#224;

à
+

&#225;

á
+

&#226;

â
+

&#227;

ã
+

&#228;

ä
+

&#229;

å
+

&#230;

æ
+

&#231;

ç
+

&#232;

è
+

&#233;

é
+

&#234;

ê
+

&#235;

ë
+

&#236;

ì
+

&#237;

í
+

&#238;

î
+

&#239;

ï
+

&#240;

ð
+

&#241;

ñ
+

&#242;

ò
+

&#243;

ó
+

&#244;

ô
+

&#245;

õ
+

&#246;

ö
+

&#247;

÷
+

&#248;

ø
+

&#249;

ù
+

&#250;

ú
+

&#251;

û
+

&#252;

ü
+

&#253;

ý
+

&#254;

þ
+

&#255;

ÿ
+

&#338;

Œ
+

&#339;

œ
+

&#376;

Ÿ
+

&#710;

ˆ
+

&#732;

˜
+

&#8192;

 
+

&#8193;

+

&#8194;

+

&#8195;

+

&#8196;

+

&#8197;

+

&#8198;

+

&#8199;

+

&#8200;

+

&#8201;

+

&#8202;

+

&#8208;

+

&#8209;

+

&#8210;

+

&#8211;

+

&#8212;

+

&#8216;

+

&#8217;

+

&#8218;

+

&#8220;

+

&#8221;

+

&#8222;

+

&#8226;

+

&#8230;

+

&#8239;

+

&#8249;

+

&#8250;

+

&#8287;

+

&#8364;

+

&#8482;

+

&#9724;

+
+
+ + +
+
+ + +
+ +
+ +
+
+
+

Installing Webfonts

+ +

Webfonts are supported by all major browser platforms but not all in the same way. There are currently four different font formats that must be included in order to target all browsers. This includes TTF, WOFF, EOT and SVG.

+ +

1. Upload your webfonts

+

You must upload your webfont kit to your website. They should be in or near the same directory as your CSS files.

+ +

2. Include the webfont stylesheet

+

A special CSS @font-face declaration helps the various browsers select the appropriate font it needs without causing you a bunch of headaches. Learn more about this syntax by reading the Fontspring blog post about it. The code for it is as follows:

+ + + +@font-face{ + font-family: 'MyWebFont'; + src: url('WebFont.eot'); + src: url('WebFont.eot?#iefix') format('embedded-opentype'), + url('WebFont.woff') format('woff'), + url('WebFont.ttf') format('truetype'), + url('WebFont.svg#webfont') format('svg'); +} + + +

We've already gone ahead and generated the code for you. All you have to do is link to the stylesheet in your HTML, like this:

+ <link rel="stylesheet" href="stylesheet.css" type="text/css" charset="utf-8" /> + +

3. Modify your own stylesheet

+

To take advantage of your new fonts, you must tell your stylesheet to use them. Look at the original @font-face declaration above and find the property called "font-family." The name linked there will be what you use to reference the font. Prepend that webfont name to the font stack in the "font-family" property, inside the selector you want to change. For example:

+p { font-family: 'WebFont', Arial, sans-serif; } + +

4. Test

+

Getting webfonts to work cross-browser can be tricky. Use the information in the sidebar to help you if you find that fonts aren't loading in a particular browser.

+
+ + +
+ +
+ +
+ +
+ + diff --git a/css/florsn41-webfont.eot b/css/florsn41-webfont.eot new file mode 100644 index 0000000..8f2af28 Binary files /dev/null and b/css/florsn41-webfont.eot differ diff --git a/css/florsn41-webfont.svg b/css/florsn41-webfont.svg new file mode 100644 index 0000000..b18fde1 --- /dev/null +++ b/css/florsn41-webfont.svg @@ -0,0 +1,342 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/css/florsn41-webfont.ttf b/css/florsn41-webfont.ttf new file mode 100644 index 0000000..b3de6e3 Binary files /dev/null and b/css/florsn41-webfont.ttf differ diff --git a/css/florsn41-webfont.woff b/css/florsn41-webfont.woff new file mode 100644 index 0000000..879ee91 Binary files /dev/null and b/css/florsn41-webfont.woff differ diff --git a/css/florsn41-webfont.woff2 b/css/florsn41-webfont.woff2 new file mode 100644 index 0000000..0cafd00 Binary files /dev/null and b/css/florsn41-webfont.woff2 differ diff --git a/css/generator_config.txt b/css/generator_config.txt new file mode 100644 index 0000000..c71db93 --- /dev/null +++ b/css/generator_config.txt @@ -0,0 +1,5 @@ +# Font Squirrel Font-face Generator Configuration File +# Upload this file to the generator to recreate the settings +# you used to create these fonts. + +{"mode":"optimal","formats":["ttf","woff","woff2","eotz"],"tt_instructor":"default","fix_vertical_metrics":"Y","fix_gasp":"xy","add_spaces":"Y","add_hyphens":"Y","fallback":"none","fallback_custom":"100","options_subset":"basic","subset_custom":"","subset_custom_range":"","subset_ot_features_list":"","css_stylesheet":"stylesheet.css","filename_suffix":"-webfont","emsquare":"2048","spacing_adjustment":"0"} \ No newline at end of file diff --git a/css/stylesheet.css b/css/stylesheet.css new file mode 100644 index 0000000..317b125 --- /dev/null +++ b/css/stylesheet.css @@ -0,0 +1,32 @@ +/* Generated by Font Squirrel (http://www.fontsquirrel.com) on December 9, 2014 */ + + + +@font-face { + font-family: 'florencesans_shadedregular'; + src: url('florsn41-webfont.eot'); + src: url('florsn41-webfont.eot?#iefix') format('embedded-opentype'), + url('florsn41-webfont.woff2') format('woff2'), + url('florsn41-webfont.woff') format('woff'), + url('florsn41-webfont.ttf') format('truetype'), + url('florsn41-webfont.svg#florencesans_shadedregular') format('svg'); + font-weight: normal; + font-style: normal; + +} + + + + +@font-face { + font-family: 'florencesansregular'; + src: url('florsn01-webfont.eot'); + src: url('florsn01-webfont.eot?#iefix') format('embedded-opentype'), + url('florsn01-webfont.woff2') format('woff2'), + url('florsn01-webfont.woff') format('woff'), + url('florsn01-webfont.ttf') format('truetype'), + url('florsn01-webfont.svg#florencesansregular') format('svg'); + font-weight: normal; + font-style: normal; + +} \ No newline at end of file diff --git a/css/webfontkit-20141209-010957.zip b/css/webfontkit-20141209-010957.zip new file mode 100644 index 0000000..e47b042 Binary files /dev/null and b/css/webfontkit-20141209-010957.zip differ diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..86a733f Binary files /dev/null and b/favicon.ico differ diff --git a/humanhash.py b/humanhash.py new file mode 100644 index 0000000..b9380df --- /dev/null +++ b/humanhash.py @@ -0,0 +1,142 @@ +""" +humanhash: Human-readable representations of digests. + +The simplest ways to use this module are the :func:`humanize` and :func:`uuid` +functions. For tighter control over the output, see :class:`HumanHasher`. +""" + +import operator +import uuid as uuidlib + + +DEFAULT_WORDLIST = ( + 'ack', 'alabama', 'alanine', 'alaska', 'alpha', 'angel', 'apart', 'april', + 'arizona', 'arkansas', 'artist', 'asparagus', 'aspen', 'august', 'autumn', + 'avocado', 'bacon', 'bakerloo', 'batman', 'beer', 'berlin', 'beryllium', + 'black', 'blossom', 'blue', 'bluebird', 'bravo', 'bulldog', 'burger', + 'butter', 'california', 'carbon', 'cardinal', 'carolina', 'carpet', 'cat', + 'ceiling', 'charlie', 'chicken', 'coffee', 'cola', 'cold', 'colorado', + 'comet', 'connecticut', 'crazy', 'cup', 'dakota', 'december', 'delaware', + 'delta', 'diet', 'don', 'double', 'early', 'earth', 'east', 'echo', + 'edward', 'eight', 'eighteen', 'eleven', 'emma', 'enemy', 'equal', + 'failed', 'fanta', 'fifteen', 'fillet', 'finch', 'fish', 'five', 'fix', + 'floor', 'florida', 'football', 'four', 'fourteen', 'foxtrot', 'freddie', + 'friend', 'fruit', 'gee', 'georgia', 'glucose', 'golf', 'green', 'grey', + 'hamper', 'happy', 'harry', 'hawaii', 'helium', 'high', 'hot', 'hotel', + 'hydrogen', 'idaho', 'illinois', 'india', 'indigo', 'ink', 'iowa', + 'island', 'item', 'jersey', 'jig', 'johnny', 'juliet', 'july', 'jupiter', + 'kansas', 'kentucky', 'kilo', 'king', 'kitten', 'lactose', 'lake', 'lamp', + 'lemon', 'leopard', 'lima', 'lion', 'lithium', 'london', 'louisiana', + 'low', 'magazine', 'magnesium', 'maine', 'mango', 'march', 'mars', + 'maryland', 'massachusetts', 'may', 'mexico', 'michigan', 'mike', + 'minnesota', 'mirror', 'mississippi', 'missouri', 'mobile', 'mockingbird', + 'monkey', 'montana', 'moon', 'mountain', 'muppet', 'music', 'nebraska', + 'neptune', 'network', 'nevada', 'nine', 'nineteen', 'nitrogen', 'north', + 'november', 'nuts', 'october', 'ohio', 'oklahoma', 'one', 'orange', + 'oranges', 'oregon', 'oscar', 'oven', 'oxygen', 'papa', 'paris', 'pasta', + 'pennsylvania', 'pip', 'pizza', 'pluto', 'potato', 'princess', 'purple', + 'quebec', 'queen', 'quiet', 'red', 'river', 'robert', 'robin', 'romeo', + 'rugby', 'sad', 'salami', 'saturn', 'september', 'seven', 'seventeen', + 'shade', 'sierra', 'single', 'sink', 'six', 'sixteen', 'skylark', 'snake', + 'social', 'sodium', 'solar', 'south', 'spaghetti', 'speaker', 'spring', + 'stairway', 'steak', 'stream', 'summer', 'sweet', 'table', 'tango', 'ten', + 'tennessee', 'tennis', 'texas', 'thirteen', 'three', 'timing', 'triple', + 'twelve', 'twenty', 'two', 'uncle', 'undress', 'uniform', 'uranus', 'utah', + 'vegan', 'venus', 'vermont', 'victor', 'video', 'violet', 'virginia', + 'washington', 'west', 'whiskey', 'white', 'william', 'winner', 'winter', + 'wisconsin', 'wolfram', 'wyoming', 'xray', 'yankee', 'yellow', 'zebra', + 'zulu') + + +class HumanHasher(object): + + """ + Transforms hex digests to human-readable strings. + + The format of these strings will look something like: + `victor-bacon-zulu-lima`. The output is obtained by compressing the input + digest to a fixed number of bytes, then mapping those bytes to one of 256 + words. A default wordlist is provided, but you can override this if you + prefer. + + As long as you use the same wordlist, the output will be consistent (i.e. + the same digest will always render the same representation). + """ + + def __init__(self, wordlist=DEFAULT_WORDLIST): + if len(wordlist) != 256: + raise ArgumentError("Wordlist must have exactly 256 items") + self.wordlist = wordlist + + def humanize(self, hexdigest, words=4, separator='-'): + + """ + Humanize a given hexadecimal digest. + + Change the number of words output by specifying `words`. Change the + word separator with `separator`. + + >>> digest = '60ad8d0d871b6095808297' + >>> HumanHasher().humanize(digest) + 'sodium-magnesium-nineteen-hydrogen' + """ + + # Gets a list of byte values between 0-255. + bytes = map(lambda x: int(x, 16), + map(''.join, zip(hexdigest[::2], hexdigest[1::2]))) + # Compress an arbitrary number of bytes to `words`. + compressed = self.compress(bytes, words) + # Map the compressed byte values through the word list. + return separator.join(self.wordlist[byte] for byte in compressed) + + @staticmethod + def compress(bytes, target): + + """ + Compress a list of byte values to a fixed target length. + + >>> bytes = [96, 173, 141, 13, 135, 27, 96, 149, 128, 130, 151] + >>> HumanHasher.compress(bytes, 4) + [205, 128, 156, 96] + + Attempting to compress a smaller number of bytes to a larger number is + an error: + + >>> HumanHasher.compress(bytes, 15) # doctest: +ELLIPSIS + Traceback (most recent call last): + ... + ValueError: Fewer input bytes than requested output + """ + + length = len(bytes) + if target > length: + raise ValueError("Fewer input bytes than requested output") + + # Split `bytes` into `target` segments. + seg_size = length // target + segments = [bytes[i * seg_size:(i + 1) * seg_size] + for i in xrange(target)] + # Catch any left-over bytes in the last segment. + segments[-1].extend(bytes[target * seg_size:]) + + # Use a simple XOR checksum-like function for compression. + checksum = lambda bytes: reduce(operator.xor, bytes, 0) + checksums = map(checksum, segments) + return checksums + + def uuid(self, **params): + + """ + Generate a UUID with a human-readable representation. + + Returns `(human_repr, full_digest)`. Accepts the same keyword arguments + as :meth:`humanize` (they'll be passed straight through). + """ + + digest = str(uuidlib.uuid4()).replace('-', '') + return self.humanize(digest, **params), digest + + +DEFAULT_HASHER = HumanHasher() +uuid = DEFAULT_HASHER.uuid +humanize = DEFAULT_HASHER.humanize diff --git a/humanhash.pyc b/humanhash.pyc new file mode 100644 index 0000000..5b655f2 Binary files /dev/null and b/humanhash.pyc differ diff --git a/images/logo.png b/images/logo.png new file mode 100644 index 0000000..8fba919 Binary files /dev/null and b/images/logo.png differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..25a7f5c --- /dev/null +++ b/index.html @@ -0,0 +1,69 @@ + + + Preposter.us + + + + + +
+ Welcome to Preposter.us! +
+
+

these are the blogs...

+
+ +
+
+ + + + + diff --git a/postindextemplate.html b/postindextemplate.html new file mode 100644 index 0000000..c6a36d5 --- /dev/null +++ b/postindextemplate.html @@ -0,0 +1,87 @@ + + + {0}'s Preposter.us Blog + + + + +
+ {0}'s Preposter.us Blog +
+
+

Posts

+
+ +
+
+ + + + + diff --git a/postrssindextemplate.xml b/postrssindextemplate.xml new file mode 100644 index 0000000..ce8a6fd --- /dev/null +++ b/postrssindextemplate.xml @@ -0,0 +1,8 @@ + + + + {0} + {1} + {2} + + \ No newline at end of file diff --git a/posttemplate.html b/posttemplate.html new file mode 100644 index 0000000..1c89472 --- /dev/null +++ b/posttemplate.html @@ -0,0 +1,100 @@ + + + + {0} + + + + +
+
+ {1}'s Preposter.us Blog +
+ +
+ {2} +
+
+ + + diff --git a/preposter.us.cfg.template b/preposter.us.cfg.template new file mode 100644 index 0000000..82d9ccf --- /dev/null +++ b/preposter.us.cfg.template @@ -0,0 +1,13 @@ +[mailserver] +imap_server: +smtp_server: +smtp_port: +email_address: +email_password: + +[webserver] +web_hostname: +web_filesystem_root: + +[system] +admin_email: diff --git a/preposter.us.py b/preposter.us.py new file mode 100755 index 0000000..4e23aa6 --- /dev/null +++ b/preposter.us.py @@ -0,0 +1,291 @@ +#!/usr/bin/python +import imaplib +import email +import os +import hashlib +import smtplib +import sys +import mimetypes +import unicodedata +import re +import ConfigParser +import shutil +import traceback +import humanhash +import json +import xml.etree.ElementTree as ET +#import dateutil +from email.mime.text import MIMEText + +# load config +config = ConfigParser.RawConfigParser() +config.read('preposter.us.cfg') + +IMAP_SERVER = config.get('mailserver', 'imap_server') +SMTP_SERVER = config.get('mailserver', 'smtp_server') +SMTP_PORT = config.get('mailserver', 'smtp_port') +EMAIL_ADDRESS = config.get('mailserver', 'email_address') +EMAIL_PASSWORD = config.get('mailserver', 'email_password') +WEB_HOST = config.get('webserver', 'web_hostname') +WEB_ROOT = config.get('webserver', 'web_filesystem_root') +ADMIN_EMAIL = config.get('system', 'admin_email') + +class Post(object): + title = '' + slug = '' + author = '' + date = '' + url = '' + +def unpack_message(uid, message, blog_dir): + email_body = '' + html_body = '' + text_body = '' + counter = 1 + for part in message.walk(): + + if part.get_content_maintype() == 'multipart': + continue + + # extract message body + if part.get_content_type() == 'text/html': + html_body = part.get_payload(decode=True) + + if part.get_content_type() == 'text/plain': + text_body += part.get_payload(decode=True) + + filename = part.get_filename() + if not filename: + ext = mimetypes.guess_extension(part.get_content_type()) + if not ext: + # Use a generic bag-of-bits extension + ext = '.bin' + filename = 'part-%03d%s' % (counter, ext) + + filename = '%s-%s' % (uid, filename) + + # only store files we know what to do with + store_file = False + + # caps just makes comparisons harder + filename = filename.lower() + + # handle images + if filename.find('.jpg') > 0 or filename.find('.jpeg') > 0 or filename.find('.png') > 0 or filename.find('.gif') > 0 or filename.find('.pdf') > 0: + store_file = True + + if part.get('Content-ID'): + cid = 'cid:%s' % part.get('Content-ID')[1:-1] + # if we can find the file embedded, update the link + if html_body.find(cid) > -1: + # re-write CID img tag to use stored filename + html_body = html_body.replace(cid, 'assets/%s' % filename) + else: + # otherwise, just embed the file + email_body = email_body + '
' % (filename, filename) + + # handle video + if filename.find('.mov') > 0 or filename.find('.mp4') > 0 or filename.find('.ogg') > 0 : + store_file = True + email_body = email_body + '' % filename + + # handle audio + if filename.find('.mp3') > 0 or filename.find('.wav') > 0 or filename.find('.m4a') > 0: + store_file = True + email_body = email_body + '' % filename + + if store_file: + counter += 1 + fp = open(os.path.join(blog_dir, 'assets', filename), 'wb') + fp.write(part.get_payload(decode=True)) + fp.close() + + if html_body: + email_body = html_body + email_body + else: + email_body = text_body + email_body + + return email_body + +def send_notification(destination_email, subject, message): + # assemble email + message = MIMEText(message) + message['Subject'] = subject + message['From'] = EMAIL_ADDRESS + message['To'] = destination_email + + # send + s = smtplib.SMTP(SMTP_SERVER + ':' + SMTP_PORT) + s.ehlo() + s.starttls() + s.login(EMAIL_ADDRESS, EMAIL_PASSWORD) + s.sendmail(EMAIL_ADDRESS, destination_email, message.as_string()) + s.quit() + +# get messages +imap_search = 'UNSEEN' +suppress_notification = False +if len(sys.argv) > 1: + if sys.argv[1] == 'rebuild': + shutil.copy('index.html', WEB_ROOT) + shutil.copytree('css', WEB_ROOT + '/css') + imap_search = 'ALL' + suppress_notification = True + +mailbox = imaplib.IMAP4_SSL(IMAP_SERVER) +mailbox.login(EMAIL_ADDRESS, EMAIL_PASSWORD) +mailbox.select() +result, data = mailbox.uid('search', None, imap_search) +uid_list = data.pop().split(' ') + +# if there's no valid uid in the list, skip it +if uid_list[0] != '': + for uid in uid_list: + + # global exception handlers like this are for bad programmers + try: + + # fetch message + latest_email_uid = uid + result, data = mailbox.uid('fetch', latest_email_uid, '(RFC822)') + raw_email = data[0][1] + + email_message = email.message_from_string(raw_email) + email_from = email.utils.parseaddr(email_message['From']) + email_address = email_from[1] + + # assemble post components + post_author = email_address.split('@')[0] + post_date = email_message['Date'] + post_title = email_message['Subject'] + + post_slug = unicodedata.normalize('NFKD', unicode(post_title)) + post_slug = post_slug.encode('ascii', 'ignore').lower() + post_slug = re.sub(r'[^a-z0-9]+', '-', post_slug).strip('-') + post_slug = re.sub(r'[-]+', '-', post_slug) + + # check for blog subdir + email_hash = hashlib.md5() + email_hash.update(email_address) + blog_directory = email_hash.hexdigest() + blog_physical_path = WEB_ROOT + '/' + blog_directory + humane_blog_name = humanhash.humanize(blog_directory) + if not os.path.exists(WEB_ROOT + '/' + blog_directory): + + # create directory for new blog + os.makedirs(blog_physical_path) + os.makedirs(os.path.join(blog_physical_path, 'assets')) + + # copy over the default stylsheet + shutil.copytree('css', blog_physical_path + '/css') + + # create human-readable link to blog directory + os.symlink(blog_directory, os.path.join(WEB_ROOT, humane_blog_name)) + + # create html blog post index + template = open('postindextemplate.html', 'r').read() + new_index = template + new_index = new_index.replace('{0}', post_author) + new_index = new_index.replace('{1}', blog_directory) + + blog_index = open(blog_physical_path + '/index.html', 'w') + blog_index.write(new_index) + blog_index.close() + + # create rss blog post index + template = open('postrssindextemplate.xml', 'r').read() + new_index = template + new_index = new_index.replace('{0}', '%s\'s Preposter.us Blog' % post_author) + new_index = new_index.replace('{1}', 'http://%s/%s' % (WEB_HOST, humane_blog_name)) + new_index = new_index.replace('{2}', '%s\'s blog on preposter.us' % post_author) + + blog_index = open(blog_physical_path + '/rss.xml', 'w') + blog_index.write(new_index) + blog_index.close() + + # add new blog to site index + blog_index_partial = open(WEB_ROOT + '/blogs.html', 'a') + blog_index_partial.write('
  • %s
  • \n' % (humane_blog_name, post_author)) + blog_index_partial.close() + + if not suppress_notification: + send_notification(email_address, 'Your new Preposter.us blog is ready!', 'You just created a Preposter.us blog, a list of your posts can be found here: http://%s/%s . Find out more about Preposter.us by visiting the project repository at https://github.com/jjg/preposter.us' % (WEB_HOST, humane_blog_name)) + + post_physical_path = blog_physical_path + '/' + post_slug + '.html' + + # if necessary, update post index + if not os.path.exists(post_physical_path): + + # update post index partial + post_index_partial = open(blog_physical_path + '/posts.html', 'a') + post_index_partial.write('
  • %s - %s
  • ' % (post_slug, post_title, post_date)) + post_index_partial.close() + + # update post index json + post = Post() + post.title = post_title + post.slug = post_slug + post.author = post_author + post.date = post_date + post.url = 'http://' + WEB_HOST + '/' + humane_blog_name + '/' + post_slug + '.html' + + # create a new index or update an existing one + json_index_physical_path = blog_physical_path + '/posts.json' + post_index_obj = {'posts':[]} + if os.path.exists(json_index_physical_path): + post_index_json = open(json_index_physical_path, 'r') + post_index_obj = json.loads(post_index_json.read()) + post_index_json.close() + + # TODO: find a more elegant way to do this than .__dict__ + post_index_obj['posts'].append({'post':post.__dict__}) + post_index_json = open(json_index_physical_path, 'w') + post_index_json.write(json.dumps(post_index_obj)) + post_index_json.close() + + # update rss feed + rss_physical_path = blog_physical_path + '/rss.xml' + tree = ET.parse(rss_physical_path) + root = tree.getroot() + + # add new post + channel = root.find('channel') + item = ET.SubElement(channel, 'item') + item_title = ET.SubElement(item, 'title') + item_link = ET.SubElement(item, 'link') + item_guid = ET.SubElement(item, 'guid') + item_pub_date = ET.SubElement(item, 'pubDate') + item_description = ET.SubElement(item, 'description') + + item_title.text = post.title + item_link.text = post.url + item_guid.text = post.url + item_pub_date.text = post.date + item_description.text = 'a post about %s by %s' % (post.title, post.author) + + # save changes + tree.write(rss_physical_path) + + + # generate post + post_body = unpack_message(uid, email_message, blog_physical_path) + + post_template = open('posttemplate.html', 'r').read() + new_post = post_template + new_post = new_post.replace('{0}', post_title) + new_post = new_post.replace('{1}', post_author) + new_post = new_post.replace('{2}', post_body) + new_post = new_post.replace('{3}', '') + + post_file = open(post_physical_path, 'w') + post_file.write(new_post) + post_file.close() + + if not suppress_notification: + send_notification(email_address, 'Preposter.us Post Posted!', 'Your post \"%s\" has been posted, you can view it here: http://%s/%s/%s.html' % (post_title, WEB_HOST, humane_blog_name, post_slug)) + + except: + print '****************************************' + print traceback.format_exc() + print raw_email + print '****************************************'